]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
merged the modularization branch (credentials) back to trunk
authorMartin Willi <martin@strongswan.org>
Thu, 13 Mar 2008 14:14:44 +0000 (14:14 -0000)
committerMartin Willi <martin@strongswan.org>
Thu, 13 Mar 2008 14:14:44 +0000 (14:14 -0000)
495 files changed:
Doxyfile.in
configure.in
scripts/cfg-leak
src/Makefile.am
src/charon/Makefile.am
src/charon/bus/bus.c
src/charon/bus/bus.h
src/charon/bus/listeners/file_logger.c
src/charon/bus/listeners/file_logger.h
src/charon/bus/listeners/sys_logger.c
src/charon/bus/listeners/sys_logger.h
src/charon/config/backend.h [new file with mode: 0644]
src/charon/config/backend_manager.c
src/charon/config/backend_manager.h
src/charon/config/backends/backend.h [deleted file]
src/charon/config/backends/local_backend.c [deleted file]
src/charon/config/backends/local_backend.h [deleted file]
src/charon/config/backends/sqlite_backend.c [deleted file]
src/charon/config/backends/writeable_backend.h [deleted file]
src/charon/config/child_cfg.c
src/charon/config/child_cfg.h
src/charon/config/credentials/local_credential_store.c [deleted file]
src/charon/config/credentials/local_credential_store.h [deleted file]
src/charon/config/ike_cfg.c
src/charon/config/ike_cfg.h
src/charon/config/peer_cfg.c
src/charon/config/peer_cfg.h
src/charon/config/proposal.c
src/charon/config/proposal.h
src/charon/config/traffic_selector.c
src/charon/config/traffic_selector.h
src/charon/control/controller.c [moved from src/charon/control/interface_manager.c with 72% similarity]
src/charon/control/controller.h [moved from src/charon/control/interface_manager.h with 55% similarity]
src/charon/control/interfaces/interface.h [deleted file]
src/charon/control/interfaces/stroke_interface.c [deleted file]
src/charon/credentials/auth_info.c [new file with mode: 0644]
src/charon/credentials/auth_info.h [new file with mode: 0644]
src/charon/credentials/credential_manager.c [new file with mode: 0644]
src/charon/credentials/credential_manager.h [new file with mode: 0644]
src/charon/credentials/credential_set.h [new file with mode: 0644]
src/charon/daemon.c
src/charon/daemon.h
src/charon/encoding/generator.c
src/charon/encoding/generator.h
src/charon/encoding/message.c
src/charon/encoding/message.h
src/charon/encoding/parser.c
src/charon/encoding/parser.h
src/charon/encoding/payloads/auth_payload.c
src/charon/encoding/payloads/auth_payload.h
src/charon/encoding/payloads/cert_payload.c
src/charon/encoding/payloads/cert_payload.h
src/charon/encoding/payloads/certreq_payload.c
src/charon/encoding/payloads/certreq_payload.h
src/charon/encoding/payloads/configuration_attribute.c
src/charon/encoding/payloads/configuration_attribute.h
src/charon/encoding/payloads/cp_payload.c
src/charon/encoding/payloads/cp_payload.h
src/charon/encoding/payloads/delete_payload.c
src/charon/encoding/payloads/delete_payload.h
src/charon/encoding/payloads/eap_payload.c
src/charon/encoding/payloads/eap_payload.h
src/charon/encoding/payloads/encodings.c
src/charon/encoding/payloads/encodings.h
src/charon/encoding/payloads/encryption_payload.c
src/charon/encoding/payloads/encryption_payload.h
src/charon/encoding/payloads/endpoint_notify.c
src/charon/encoding/payloads/endpoint_notify.h
src/charon/encoding/payloads/id_payload.c
src/charon/encoding/payloads/id_payload.h
src/charon/encoding/payloads/ike_header.c
src/charon/encoding/payloads/ike_header.h
src/charon/encoding/payloads/ke_payload.c
src/charon/encoding/payloads/ke_payload.h
src/charon/encoding/payloads/nonce_payload.c
src/charon/encoding/payloads/nonce_payload.h
src/charon/encoding/payloads/notify_payload.c
src/charon/encoding/payloads/notify_payload.h
src/charon/encoding/payloads/payload.c
src/charon/encoding/payloads/payload.h
src/charon/encoding/payloads/proposal_substructure.c
src/charon/encoding/payloads/proposal_substructure.h
src/charon/encoding/payloads/sa_payload.c
src/charon/encoding/payloads/sa_payload.h
src/charon/encoding/payloads/traffic_selector_substructure.c
src/charon/encoding/payloads/traffic_selector_substructure.h
src/charon/encoding/payloads/transform_attribute.c
src/charon/encoding/payloads/transform_attribute.h
src/charon/encoding/payloads/transform_substructure.c
src/charon/encoding/payloads/transform_substructure.h
src/charon/encoding/payloads/ts_payload.c
src/charon/encoding/payloads/ts_payload.h
src/charon/encoding/payloads/unknown_payload.c
src/charon/encoding/payloads/unknown_payload.h
src/charon/encoding/payloads/vendor_id_payload.c
src/charon/encoding/payloads/vendor_id_payload.h
src/charon/kernel/kernel_interface.c
src/charon/kernel/kernel_interface.h
src/charon/network/packet.c
src/charon/network/packet.h
src/charon/network/receiver.c
src/charon/network/receiver.h
src/charon/network/sender.c
src/charon/network/sender.h
src/charon/network/socket-raw.c
src/charon/network/socket.c
src/charon/network/socket.h
src/charon/plugins/dbus/Makefile.am [new file with mode: 0644]
src/charon/plugins/dbus/dbus.c [moved from src/charon/control/interfaces/dbus_interface.c with 82% similarity]
src/charon/plugins/dbus/dbus.h [new file with mode: 0644]
src/charon/plugins/eap_aka/Makefile.am [new file with mode: 0644]
src/charon/plugins/eap_aka/eap_aka.c [moved from src/charon/sa/authenticators/eap/eap_aka.c with 81% similarity]
src/charon/plugins/eap_aka/eap_aka.h [moved from src/charon/sa/authenticators/eap/eap_aka.h with 59% similarity]
src/charon/plugins/eap_aka/eap_aka_plugin.c [new file with mode: 0644]
src/charon/plugins/eap_aka/eap_aka_plugin.h [new file with mode: 0644]
src/charon/plugins/eap_identity/Makefile.am [new file with mode: 0644]
src/charon/plugins/eap_identity/eap_identity.c [moved from src/charon/sa/authenticators/eap/eap_identity.c with 87% similarity]
src/charon/plugins/eap_identity/eap_identity.h [moved from src/charon/sa/authenticators/eap/eap_identity.h with 66% similarity]
src/charon/plugins/eap_identity/eap_identity_plugin.c [new file with mode: 0644]
src/charon/plugins/eap_identity/eap_identity_plugin.h [new file with mode: 0644]
src/charon/plugins/eap_md5/Makefile.am [new file with mode: 0644]
src/charon/plugins/eap_md5/eap_md5.c [moved from src/charon/sa/authenticators/eap/eap_md5.c with 78% similarity]
src/charon/plugins/eap_md5/eap_md5.h [moved from src/charon/sa/authenticators/eap/eap_md5.h with 62% similarity]
src/charon/plugins/eap_md5/eap_md5_plugin.c [new file with mode: 0644]
src/charon/plugins/eap_md5/eap_md5_plugin.h [new file with mode: 0644]
src/charon/plugins/eap_sim/Makefile.am [new file with mode: 0644]
src/charon/plugins/eap_sim/eap_sim.c [moved from src/charon/sa/authenticators/eap/eap_sim.c with 93% similarity]
src/charon/plugins/eap_sim/eap_sim.h [moved from src/charon/sa/authenticators/eap/eap_sim.h with 82% similarity]
src/charon/plugins/eap_sim/eap_sim_file.c [moved from src/charon/sa/authenticators/eap/sim/eap_sim_file.c with 94% similarity]
src/charon/plugins/eap_sim/eap_sim_plugin.c [new file with mode: 0644]
src/charon/plugins/eap_sim/eap_sim_plugin.h [new file with mode: 0644]
src/charon/plugins/med_db/Makefile.am [new file with mode: 0644]
src/charon/plugins/med_db/med_db_creds.c [new file with mode: 0644]
src/charon/plugins/med_db/med_db_creds.h [new file with mode: 0644]
src/charon/plugins/med_db/med_db_plugin.c [new file with mode: 0644]
src/charon/plugins/med_db/med_db_plugin.h [new file with mode: 0644]
src/charon/plugins/sql/Makefile.am [new file with mode: 0644]
src/charon/plugins/sql/config.sql [new file with mode: 0644]
src/charon/plugins/sql/cred.sql [new file with mode: 0644]
src/charon/plugins/sql/sql_config.c [new file with mode: 0644]
src/charon/plugins/sql/sql_config.h [moved from src/charon/config/backends/sqlite_backend.h with 54% similarity]
src/charon/plugins/sql/sql_plugin.c [new file with mode: 0644]
src/charon/plugins/sql/sql_plugin.h [new file with mode: 0644]
src/charon/plugins/sql/test.sql [new file with mode: 0644]
src/charon/plugins/stroke/Makefile.am [new file with mode: 0644]
src/charon/plugins/stroke/stroke.c [new file with mode: 0755]
src/charon/plugins/stroke/stroke.h [moved from src/charon/control/interfaces/stroke_interface.h with 52% similarity]
src/charon/plugins/unit_tester/Makefile.am [new file with mode: 0644]
src/charon/plugins/unit_tester/tests.h [new file with mode: 0644]
src/charon/plugins/unit_tester/tests/test_auth_info.c [new file with mode: 0644]
src/charon/plugins/unit_tester/tests/test_curl.c [new file with mode: 0644]
src/charon/plugins/unit_tester/tests/test_enumerator.c [new file with mode: 0644]
src/charon/plugins/unit_tester/tests/test_fips_prf.c [new file with mode: 0644]
src/charon/plugins/unit_tester/tests/test_mutex.c [new file with mode: 0644]
src/charon/plugins/unit_tester/tests/test_mysql.c [new file with mode: 0644]
src/charon/plugins/unit_tester/tests/test_sqlite.c [new file with mode: 0644]
src/charon/plugins/unit_tester/unit_tester.c [new file with mode: 0644]
src/charon/plugins/unit_tester/unit_tester.h [moved from src/charon/control/interfaces/xml_interface.h with 51% similarity]
src/charon/plugins/xml/Makefile.am [new file with mode: 0644]
src/charon/plugins/xml/schema.xml [moved from src/charon/control/interfaces/xml_interface.xml with 100% similarity]
src/charon/plugins/xml/xml.c [moved from src/charon/control/interfaces/xml_interface.c with 92% similarity]
src/charon/plugins/xml/xml.h [moved from src/charon/control/interfaces/dbus_interface.h with 50% similarity]
src/charon/processing/jobs/acquire_job.c
src/charon/processing/jobs/acquire_job.h
src/charon/processing/jobs/callback_job.c
src/charon/processing/jobs/callback_job.h
src/charon/processing/jobs/delete_child_sa_job.c
src/charon/processing/jobs/delete_child_sa_job.h
src/charon/processing/jobs/delete_ike_sa_job.c
src/charon/processing/jobs/delete_ike_sa_job.h
src/charon/processing/jobs/initiate_mediation_job.c
src/charon/processing/jobs/initiate_mediation_job.h
src/charon/processing/jobs/job.h
src/charon/processing/jobs/mediation_job.c
src/charon/processing/jobs/mediation_job.h
src/charon/processing/jobs/process_message_job.c
src/charon/processing/jobs/process_message_job.h
src/charon/processing/jobs/rekey_child_sa_job.c
src/charon/processing/jobs/rekey_child_sa_job.h
src/charon/processing/jobs/rekey_ike_sa_job.c
src/charon/processing/jobs/rekey_ike_sa_job.h
src/charon/processing/jobs/retransmit_job.c
src/charon/processing/jobs/retransmit_job.h
src/charon/processing/jobs/roam_job.c
src/charon/processing/jobs/roam_job.h
src/charon/processing/jobs/send_dpd_job.c
src/charon/processing/jobs/send_dpd_job.h
src/charon/processing/jobs/send_keepalive_job.c
src/charon/processing/jobs/send_keepalive_job.h
src/charon/processing/processor.c
src/charon/processing/processor.h
src/charon/processing/scheduler.c
src/charon/processing/scheduler.h
src/charon/sa/authenticators/authenticator.c
src/charon/sa/authenticators/authenticator.h
src/charon/sa/authenticators/eap/eap_manager.c [new file with mode: 0644]
src/charon/sa/authenticators/eap/eap_manager.h [new file with mode: 0644]
src/charon/sa/authenticators/eap/eap_method.c
src/charon/sa/authenticators/eap/eap_method.h
src/charon/sa/authenticators/eap_authenticator.c
src/charon/sa/authenticators/eap_authenticator.h
src/charon/sa/authenticators/psk_authenticator.c
src/charon/sa/authenticators/psk_authenticator.h
src/charon/sa/authenticators/rsa_authenticator.c
src/charon/sa/authenticators/rsa_authenticator.h
src/charon/sa/child_sa.c
src/charon/sa/child_sa.h
src/charon/sa/connect_manager.c
src/charon/sa/connect_manager.h
src/charon/sa/ike_sa.c
src/charon/sa/ike_sa.h
src/charon/sa/ike_sa_id.c
src/charon/sa/ike_sa_id.h
src/charon/sa/ike_sa_manager.c
src/charon/sa/ike_sa_manager.h
src/charon/sa/mediation_manager.c
src/charon/sa/mediation_manager.h
src/charon/sa/task_manager.c
src/charon/sa/task_manager.h
src/charon/sa/tasks/child_create.c
src/charon/sa/tasks/child_create.h
src/charon/sa/tasks/child_delete.c
src/charon/sa/tasks/child_delete.h
src/charon/sa/tasks/child_rekey.c
src/charon/sa/tasks/child_rekey.h
src/charon/sa/tasks/ike_auth.c
src/charon/sa/tasks/ike_auth.h
src/charon/sa/tasks/ike_auth_lifetime.c
src/charon/sa/tasks/ike_auth_lifetime.h
src/charon/sa/tasks/ike_cert.c [deleted file]
src/charon/sa/tasks/ike_cert_post.c [new file with mode: 0644]
src/charon/sa/tasks/ike_cert_post.h [moved from src/charon/sa/tasks/ike_cert.h with 64% similarity]
src/charon/sa/tasks/ike_cert_pre.c [new file with mode: 0644]
src/charon/sa/tasks/ike_cert_pre.h [new file with mode: 0644]
src/charon/sa/tasks/ike_config.c
src/charon/sa/tasks/ike_config.h
src/charon/sa/tasks/ike_delete.c
src/charon/sa/tasks/ike_delete.h
src/charon/sa/tasks/ike_dpd.c
src/charon/sa/tasks/ike_dpd.h
src/charon/sa/tasks/ike_init.c
src/charon/sa/tasks/ike_init.h
src/charon/sa/tasks/ike_mobike.c
src/charon/sa/tasks/ike_mobike.h
src/charon/sa/tasks/ike_natd.c
src/charon/sa/tasks/ike_natd.h
src/charon/sa/tasks/ike_p2p.c
src/charon/sa/tasks/ike_p2p.h
src/charon/sa/tasks/ike_reauth.c
src/charon/sa/tasks/ike_reauth.h
src/charon/sa/tasks/ike_rekey.c
src/charon/sa/tasks/ike_rekey.h
src/charon/sa/tasks/task.c
src/charon/sa/tasks/task.h
src/libfast/Makefile.am [new file with mode: 0644]
src/libfast/context.h [moved from src/manager/lib/context.h with 78% similarity]
src/libfast/controller.h [moved from src/manager/lib/controller.h with 67% similarity]
src/libfast/dispatcher.c [moved from src/manager/lib/dispatcher.c with 58% similarity]
src/libfast/dispatcher.h [new file with mode: 0644]
src/libfast/filter.h [new file with mode: 0644]
src/libfast/request.c [moved from src/manager/lib/request.c with 58% similarity]
src/libfast/request.h [moved from src/manager/lib/request.h with 55% similarity]
src/libfast/session.c [moved from src/manager/lib/session.c with 76% similarity]
src/libfast/session.h [moved from src/manager/lib/session.h with 68% similarity]
src/libstrongswan/Makefile.am
src/libstrongswan/asn1/asn1.c
src/libstrongswan/asn1/asn1.h
src/libstrongswan/asn1/pem.c
src/libstrongswan/asn1/pem.h
src/libstrongswan/asn1/ttodata.c
src/libstrongswan/asn1/ttodata.h
src/libstrongswan/chunk.c
src/libstrongswan/chunk.h
src/libstrongswan/credential_store.h [deleted file]
src/libstrongswan/credentials/builder.c [new file with mode: 0644]
src/libstrongswan/credentials/builder.h [new file with mode: 0644]
src/libstrongswan/credentials/certificates/certificate.c [new file with mode: 0644]
src/libstrongswan/credentials/certificates/certificate.h [new file with mode: 0644]
src/libstrongswan/credentials/certificates/crl.c [new file with mode: 0644]
src/libstrongswan/credentials/certificates/crl.h [new file with mode: 0644]
src/libstrongswan/credentials/certificates/ocsp_request.c [new file with mode: 0644]
src/libstrongswan/credentials/certificates/ocsp_request.h [new file with mode: 0644]
src/libstrongswan/credentials/certificates/ocsp_response.c [new file with mode: 0644]
src/libstrongswan/credentials/certificates/ocsp_response.h [new file with mode: 0644]
src/libstrongswan/credentials/certificates/x509.c [new file with mode: 0644]
src/libstrongswan/credentials/certificates/x509.h [new file with mode: 0644]
src/libstrongswan/credentials/credential_factory.c [new file with mode: 0644]
src/libstrongswan/credentials/credential_factory.h [new file with mode: 0644]
src/libstrongswan/credentials/keys/private_key.c [new file with mode: 0644]
src/libstrongswan/credentials/keys/private_key.h [new file with mode: 0644]
src/libstrongswan/credentials/keys/public_key.c [new file with mode: 0644]
src/libstrongswan/credentials/keys/public_key.h [new file with mode: 0644]
src/libstrongswan/credentials/keys/shared_key.c [new file with mode: 0644]
src/libstrongswan/credentials/keys/shared_key.h [new file with mode: 0644]
src/libstrongswan/crypto/ac.c [deleted file]
src/libstrongswan/crypto/ac.h [deleted file]
src/libstrongswan/crypto/ca.c [deleted file]
src/libstrongswan/crypto/ca.h [deleted file]
src/libstrongswan/crypto/certinfo.c [deleted file]
src/libstrongswan/crypto/certinfo.h [deleted file]
src/libstrongswan/crypto/crl.c [deleted file]
src/libstrongswan/crypto/crl.h [deleted file]
src/libstrongswan/crypto/crypters/crypter.c
src/libstrongswan/crypto/crypters/crypter.h
src/libstrongswan/crypto/crypto_factory.c [new file with mode: 0644]
src/libstrongswan/crypto/crypto_factory.h [new file with mode: 0644]
src/libstrongswan/crypto/diffie_hellman.c
src/libstrongswan/crypto/diffie_hellman.h
src/libstrongswan/crypto/hashers/hasher.c
src/libstrongswan/crypto/hashers/hasher.h
src/libstrongswan/crypto/ietf_attr_list.c [deleted file]
src/libstrongswan/crypto/ietf_attr_list.h [deleted file]
src/libstrongswan/crypto/ocsp.c [deleted file]
src/libstrongswan/crypto/ocsp.h
src/libstrongswan/crypto/pkcs7.c
src/libstrongswan/crypto/pkcs7.h
src/libstrongswan/crypto/pkcs9.c
src/libstrongswan/crypto/pkcs9.h
src/libstrongswan/crypto/prf_plus.c
src/libstrongswan/crypto/prf_plus.h
src/libstrongswan/crypto/prfs/prf.c
src/libstrongswan/crypto/prfs/prf.h
src/libstrongswan/crypto/rsa/rsa_private_key.c [deleted file]
src/libstrongswan/crypto/rsa/rsa_private_key.h [deleted file]
src/libstrongswan/crypto/rsa/rsa_public_key.c [deleted file]
src/libstrongswan/crypto/rsa/rsa_public_key.h [deleted file]
src/libstrongswan/crypto/signers/signer.c
src/libstrongswan/crypto/signers/signer.h
src/libstrongswan/crypto/x509.c [deleted file]
src/libstrongswan/crypto/x509.h [deleted file]
src/libstrongswan/database/database.h [new file with mode: 0644]
src/libstrongswan/database/database_factory.c [new file with mode: 0644]
src/libstrongswan/database/database_factory.h [new file with mode: 0644]
src/libstrongswan/debug.c
src/libstrongswan/debug.h
src/libstrongswan/enum.c
src/libstrongswan/enum.h
src/libstrongswan/fetcher/fetcher.h [new file with mode: 0644]
src/libstrongswan/fetcher/fetcher_manager.c [new file with mode: 0644]
src/libstrongswan/fetcher/fetcher_manager.h [new file with mode: 0644]
src/libstrongswan/fips/fips.c
src/libstrongswan/fips/fips.h
src/libstrongswan/fips/fips_canister_end.c
src/libstrongswan/fips/fips_canister_start.c
src/libstrongswan/fips/fips_signer.c
src/libstrongswan/library.c
src/libstrongswan/library.h
src/libstrongswan/plugins/aes/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/aes/aes_crypter.c [moved from src/libstrongswan/crypto/crypters/aes_cbc_crypter.c with 97% similarity]
src/libstrongswan/plugins/aes/aes_crypter.h [moved from src/libstrongswan/crypto/crypters/aes_cbc_crypter.h with 51% similarity]
src/libstrongswan/plugins/aes/aes_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/aes/aes_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/curl/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/curl/curl_fetcher.c [new file with mode: 0644]
src/libstrongswan/plugins/curl/curl_fetcher.h [new file with mode: 0644]
src/libstrongswan/plugins/curl/curl_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/curl/curl_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/des/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/des/des_crypter.c [moved from src/libstrongswan/crypto/crypters/des_crypter.c with 99% similarity]
src/libstrongswan/plugins/des/des_crypter.h [moved from src/libstrongswan/crypto/crypters/des_crypter.h with 70% similarity]
src/libstrongswan/plugins/des/des_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/des/des_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/fips_prf/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/fips_prf/fips_prf.c [moved from src/libstrongswan/crypto/prfs/fips_prf.c with 83% similarity]
src/libstrongswan/plugins/fips_prf/fips_prf.h [moved from src/libstrongswan/crypto/prfs/fips_prf.h with 60% similarity]
src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/gmp/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c [new file with mode: 0644]
src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h [new file with mode: 0644]
src/libstrongswan/plugins/gmp/gmp_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/gmp/gmp_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c [new file with mode: 0644]
src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h [new file with mode: 0644]
src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c [new file with mode: 0644]
src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h [new file with mode: 0644]
src/libstrongswan/plugins/hmac/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/hmac/hmac.c [moved from src/libstrongswan/crypto/hmac.c with 95% similarity]
src/libstrongswan/plugins/hmac/hmac.h [moved from src/libstrongswan/crypto/hmac.h with 58% similarity]
src/libstrongswan/plugins/hmac/hmac_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/hmac/hmac_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/hmac/hmac_prf.c [moved from src/libstrongswan/crypto/prfs/hmac_prf.c with 82% similarity]
src/libstrongswan/plugins/hmac/hmac_prf.h [moved from src/libstrongswan/crypto/prfs/hmac_prf.h with 62% similarity]
src/libstrongswan/plugins/hmac/hmac_signer.c [moved from src/libstrongswan/crypto/signers/hmac_signer.c with 58% similarity]
src/libstrongswan/plugins/hmac/hmac_signer.h [moved from src/libstrongswan/crypto/signers/hmac_signer.h with 63% similarity]
src/libstrongswan/plugins/ldap/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/ldap/ldap_fetcher.c [new file with mode: 0644]
src/libstrongswan/plugins/ldap/ldap_fetcher.h [new file with mode: 0644]
src/libstrongswan/plugins/ldap/ldap_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/ldap/ldap_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/md5/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/md5/md5_hasher.c [moved from src/libstrongswan/crypto/hashers/md5_hasher.c with 95% similarity]
src/libstrongswan/plugins/md5/md5_hasher.h [moved from src/libstrongswan/crypto/hashers/md5_hasher.h with 65% similarity]
src/libstrongswan/plugins/md5/md5_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/md5/md5_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/mysql/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/mysql/mysql_database.c [new file with mode: 0644]
src/libstrongswan/plugins/mysql/mysql_database.h [new file with mode: 0644]
src/libstrongswan/plugins/mysql/mysql_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/mysql/mysql_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/plugin_loader.c [new file with mode: 0644]
src/libstrongswan/plugins/plugin_loader.h [new file with mode: 0644]
src/libstrongswan/plugins/sha1/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/sha1/sha1_hasher.c [moved from src/libstrongswan/crypto/hashers/sha1_hasher.c with 88% similarity]
src/libstrongswan/plugins/sha1/sha1_hasher.h [moved from src/libstrongswan/crypto/hashers/sha1_hasher.h with 61% similarity]
src/libstrongswan/plugins/sha1/sha1_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/sha1/sha1_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/sha2/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/sha2/sha2_hasher.c [moved from src/libstrongswan/crypto/hashers/sha2_hasher.c with 94% similarity]
src/libstrongswan/plugins/sha2/sha2_hasher.h [moved from src/libstrongswan/crypto/hashers/sha2_hasher.h with 69% similarity]
src/libstrongswan/plugins/sha2/sha2_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/sha2/sha2_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/sqlite/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/sqlite/sqlite_database.c [new file with mode: 0644]
src/libstrongswan/plugins/sqlite/sqlite_database.h [new file with mode: 0644]
src/libstrongswan/plugins/sqlite/sqlite_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/sqlite/sqlite_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/x509/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_cert.c [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_cert.h [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_crl.c [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_crl.h [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_ocsp_request.c [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_ocsp_request.h [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_ocsp_response.c [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_ocsp_response.h [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/x509/x509_plugin.h [new file with mode: 0644]
src/libstrongswan/printf_hook.c
src/libstrongswan/printf_hook.h
src/libstrongswan/settings.c [new file with mode: 0644]
src/libstrongswan/settings.h [new file with mode: 0644]
src/libstrongswan/utils.c [new file with mode: 0644]
src/libstrongswan/utils.h [new file with mode: 0644]
src/libstrongswan/utils/enumerator.c
src/libstrongswan/utils/enumerator.h
src/libstrongswan/utils/fetcher.c [deleted file]
src/libstrongswan/utils/fetcher.h [deleted file]
src/libstrongswan/utils/host.c
src/libstrongswan/utils/host.h
src/libstrongswan/utils/identification.c
src/libstrongswan/utils/identification.h
src/libstrongswan/utils/iterator.h
src/libstrongswan/utils/leak_detective.c
src/libstrongswan/utils/leak_detective.h
src/libstrongswan/utils/lexparser.c
src/libstrongswan/utils/lexparser.h
src/libstrongswan/utils/linked_list.c
src/libstrongswan/utils/linked_list.h
src/libstrongswan/utils/mutex.c [new file with mode: 0644]
src/libstrongswan/utils/mutex.h [new file with mode: 0644]
src/libstrongswan/utils/optionsfrom.c
src/libstrongswan/utils/optionsfrom.h
src/libstrongswan/utils/randomizer.c
src/libstrongswan/utils/randomizer.h
src/manager/Makefile.am
src/manager/controller/auth_controller.c
src/manager/controller/auth_controller.h
src/manager/controller/config_controller.c
src/manager/controller/config_controller.h
src/manager/controller/control_controller.c
src/manager/controller/control_controller.h
src/manager/controller/gateway_controller.c
src/manager/controller/gateway_controller.h
src/manager/controller/ikesa_controller.c
src/manager/controller/ikesa_controller.h
src/manager/database.c [deleted file]
src/manager/gateway.c
src/manager/gateway.h
src/manager/lib/dispatcher.h [deleted file]
src/manager/main.c
src/manager/manager.c
src/manager/manager.h
src/manager/storage.c [new file with mode: 0644]
src/manager/storage.h [moved from src/manager/database.h with 61% similarity]
src/manager/xml.c [moved from src/manager/lib/xml.c with 98% similarity]
src/manager/xml.h [moved from src/manager/lib/xml.h with 84% similarity]
src/pluto/Makefile.am
src/scepclient/Makefile.am
src/starter/args.c
src/starter/confread.h
src/starter/invokecharon.c
src/starter/keywords.h
src/starter/keywords.txt
src/starter/starter.c
src/starter/starterstroke.c
src/starter/starterstroke.h
src/stroke/Makefile.am
src/stroke/stroke.c
src/stroke/stroke_msg.h [moved from src/stroke/stroke.h with 94% similarity]
testing/scripts/start-switches
testing/scripts/start-umls
testing/scripts/xstart-umls
testing/testing.conf

index 4e7cebb854b03f04b7ba2c445b716eaa0bdc5add..fb746a61d9223b180c2190809cb53e1bad89e65f 100644 (file)
@@ -70,12 +70,12 @@ WARN_LOGFILE =
 #---------------------------------------------------------------------------
 # configuration options related to the input files
 #---------------------------------------------------------------------------
-INPUT = src/libstrongswan src/charon
+INPUT = src/libstrongswan src/charon src/libfast src/manager
 FILE_PATTERNS = *.h
 RECURSIVE = YES
 EXCLUDE = 
 EXCLUDE_SYMLINKS = NO
-EXCLUDE_PATTERNS = 
+EXCLUDE_PATTERNS = */.svn/*
 EXAMPLE_PATH = 
 EXAMPLE_PATTERNS = 
 EXAMPLE_RECURSIVE = NO
index 6d0ffbea4c2744e01919b89094d234da03048e56..c13d19b2ee7014bd1d3672ba424f8c146209224e 100644 (file)
@@ -72,6 +72,7 @@ AC_ARG_WITH(
     [AC_SUBST(ipsecdir, "$withval")],
     [AC_SUBST(ipsecdir, "${libexecdir}/ipsec")]
 )
+AC_SUBST(plugindir, "${ipsecdir}/plugins")
 
 AC_ARG_WITH(
     [plugindir],
@@ -80,32 +81,11 @@ AC_ARG_WITH(
     [AC_SUBST(plugindir, "${ipsecdir}/plugins")]
 )
 
-AC_ARG_WITH(
-    [eapdir],
-    AS_HELP_STRING([--with-eapdir=dir],[path for pluggable EAP modules other than "plugindir/eap"]),
-    [AC_SUBST(eapdir, "$withval")],
-    [AC_SUBST(eapdir, "${plugindir}/eap")]
-)
-
-AC_ARG_WITH(
-    [backenddir],
-    AS_HELP_STRING([--with-backenddir=dir],[path for pluggable configuration backend modules other than "plugindir/backends"]),
-    [AC_SUBST(backenddir, "$withval")],
-    [AC_SUBST(backenddir, "${plugindir}/backends")]
-)
-
-AC_ARG_WITH(
-    [interfacedir],
-    AS_HELP_STRING([--with-interfacedir=dir],[path for pluggable control interface modules other than "plugindir/interfaces"]),
-    [AC_SUBST(interfacedir, "$withval")],
-    [AC_SUBST(interfacedir, "${plugindir}/interfaces")]
-)
-
 AC_ARG_WITH(
     [sim-reader],
     AS_HELP_STRING([--with-sim-reader=library.so],[library containing the sim_run_alg()/sim_get_triplet() function for EAP-SIM]),
     [AC_SUBST(simreader, "$withval")],
-    [AC_SUBST(simreader, "${plugindir}/libcharon-eapsim-file.so")]
+    [AC_SUBST(simreader, "${plugindir}/libeapsim-file.so")]
 )
 
 AC_ARG_WITH(
@@ -144,24 +124,148 @@ AC_ARG_WITH(
 )
 
 AC_ARG_ENABLE(
-    [http],
-    AS_HELP_STRING([--enable-http],[enable OCSP and fetching of Certificates and CRLs over HTTP (default is NO). Requires libcurl.]),
+    [curl],
+    AS_HELP_STRING([--enable-curl],[enable CURL fetcher plugin to fetch files via libcurl (default is NO). Requires libcurl.]),
     [if test x$enableval = xyes; then
-        http=true
-        AC_DEFINE(LIBCURL)
+        curl=true
     fi]
 )
-AM_CONDITIONAL(USE_LIBCURL, test x$http = xtrue)
+AM_CONDITIONAL(USE_CURL, test x$curl = xtrue)
 
 AC_ARG_ENABLE(
     [ldap],
-    AS_HELP_STRING([--enable-ldap],[enable fetching of CRLs from LDAP (default is NO). Requires openLDAP.]),
+    AS_HELP_STRING([--enable-ldap],[enable LDAP fetching plugin to fetch files via libldap (default is NO). Requires openLDAP.]),
     [if test x$enableval = xyes; then
         ldap=true
-        AC_DEFINE(LIBLDAP)
     fi]
 )
-AM_CONDITIONAL(USE_LIBLDAP, test x$ldap = xtrue)
+AM_CONDITIONAL(USE_LDAP, test x$ldap = xtrue)
+
+AC_ARG_ENABLE(
+    [aes],
+    AS_HELP_STRING([--disable-aes],[disable own AES software implementation plugin. (default is NO).]),
+    [if test x$enableval = xyes; then
+        aes=true
+     else
+        aes=false
+    fi],
+    aes=true
+)
+AM_CONDITIONAL(USE_AES, test x$aes = xtrue)
+
+AC_ARG_ENABLE(
+    [des],
+    AS_HELP_STRING([--disable-des],[disable own DES/3DES software implementation plugin. (default is NO).]),
+    [if test x$enableval = xyes; then
+        des=true
+     else
+        des=false
+    fi],
+    des=true
+)
+AM_CONDITIONAL(USE_DES, test x$des = xtrue)
+
+AC_ARG_ENABLE(
+    [md5],
+    AS_HELP_STRING([--disable-md5],[disable own MD5 software implementation plugin. (default is NO).]),
+    [if test x$enableval = xyes; then
+        md5=true
+     else
+        md5=false
+    fi],
+    md5=true
+)
+AM_CONDITIONAL(USE_MD5, test x$md5 = xtrue)
+
+AC_ARG_ENABLE(
+    [sha1],
+    AS_HELP_STRING([--disable-sha1],[disable own SHA1 software implementation plugin. (default is NO).]),
+    [if test x$enableval = xyes; then
+        sha1=true
+     else
+        sha1=false
+    fi],
+    sha1=true
+)
+AM_CONDITIONAL(USE_SHA1, test x$sha1 = xtrue)
+
+AC_ARG_ENABLE(
+    [sha2],
+    AS_HELP_STRING([--disable-sha2],[disable own SHA256/SHA384/SHA512 software implementation plugin. (default is NO).]),
+    [if test x$enableval = xyes; then
+        sha2=true
+     else
+        sha2=false
+    fi],
+    sha2=true
+)
+AM_CONDITIONAL(USE_SHA2, test x$sha2 = xtrue)
+
+AC_ARG_ENABLE(
+    [fips-prf],
+    AS_HELP_STRING([--disable-fips-prf],[disable FIPS PRF software implementation plugin. (default is NO).]),
+    [if test x$enableval = xyes; then
+        fips_prf=true
+     else
+        fips_prf=false
+    fi],
+    fips_prf=true
+)
+AM_CONDITIONAL(USE_FIPS_PRF, test x$fips_prf = xtrue)
+
+AC_ARG_ENABLE(
+    [gmp],
+    AS_HELP_STRING([--disable-gmp],[disable own GNU MP (libgmp) based crypto implementation plugin. (default is NO).]),
+    [if test x$enableval = xyes; then
+        gmp=true
+     else
+        gmp=false
+    fi],
+    gmp=true
+)
+AM_CONDITIONAL(USE_GMP, test x$gmp = xtrue)
+
+AC_ARG_ENABLE(
+    [x509],
+    AS_HELP_STRING([--disable-x509],[disable own X509 certificate implementation plugin. (default is NO).]),
+    [if test x$enableval = xyes; then
+        x509=true
+     else
+        x509=false
+    fi],
+    x509=true
+)
+AM_CONDITIONAL(USE_X509, test x$x509 = xtrue)
+
+AC_ARG_ENABLE(
+    [hmac],
+    AS_HELP_STRING([--disable-hmac],[disable HMAC crypto implementation plugin. (default is NO).]),
+    [if test x$enableval = xyes; then
+        hmac=true
+     else
+        hmac=false
+    fi],
+    hmac=true
+)
+AM_CONDITIONAL(USE_HMAC, test x$hmac = xtrue)
+
+AC_ARG_ENABLE(
+    [mysql],
+    AS_HELP_STRING([--enable-mysql],[enable MySQL database support (default is NO). Requires libmysqlclient_r.]),
+    [if test x$enableval = xyes; then
+        mysql=true
+    fi]
+)
+AM_CONDITIONAL(USE_MYSQL, test x$mysql = xtrue)
+
+AC_ARG_ENABLE(
+    [sqlite],
+    AS_HELP_STRING([--enable-sqlite],[enable SQLite database support (default is NO). Requires libsqlite3.]),
+    [if test x$enableval = xyes; then
+        sqlite=true
+    fi]
+)
+AM_CONDITIONAL(USE_SQLITE, test x$sqlite = xtrue)
 
 AC_ARG_ENABLE(
     [stroke],
@@ -175,6 +279,16 @@ AC_ARG_ENABLE(
 )
 AM_CONDITIONAL(USE_STROKE, test x$stroke = xtrue)
 
+AC_ARG_ENABLE(
+    [med-db],
+    AS_HELP_STRING([--enable-med-db],[enable MySQL mediation database plugin (default is NO).]),
+    [if test x$enableval = xyes; then
+        med_db=true
+        AC_DEFINE(LIBDBUS)
+    fi]
+)
+AM_CONDITIONAL(USE_MED_DB, test x$med_db = xtrue)
+
 AC_ARG_ENABLE(
     [dbus],
     AS_HELP_STRING([--enable-dbus],[enable DBUS configuration and control interface (default is NO). Requires libdbus.]),
@@ -196,14 +310,13 @@ AC_ARG_ENABLE(
 AM_CONDITIONAL(USE_LIBXML, test x$xml = xtrue)
 
 AC_ARG_ENABLE(
-    [sqlite],
-    AS_HELP_STRING([--enable-sqlite],[enable SQLite configuration backend (default is NO). Requires libsqlite3.]),
+    [sql],
+    AS_HELP_STRING([--enable-sql],[enable SQL database configuration backend (default is NO).]),
     [if test x$enableval = xyes; then
-        sqlite=true
-        AC_DEFINE(LIBSQLITE)
+        sql=true
     fi]
 )
-AM_CONDITIONAL(USE_LIBSQLITE, test x$sqlite = xtrue)
+AM_CONDITIONAL(USE_SQL, test x$sql = xtrue)
 
 AC_ARG_ENABLE(
     [smartcard],
@@ -233,6 +346,15 @@ AC_ARG_ENABLE(
 )
 AM_CONDITIONAL(USE_LEAK_DETECTIVE, test x$leak_detective = xtrue)
 
+AC_ARG_ENABLE(
+    [unit-tests],
+    AS_HELP_STRING([--enable-unit-tests],[enable unit tests on IKEv2 daemon startup (default is NO).]),
+    [if test x$enableval = xyes; then
+        unittest=true
+    fi]
+)
+AM_CONDITIONAL(USE_UNIT_TESTS, test x$unittest = xtrue)
+
 AC_ARG_ENABLE(
     [eap-sim],
     AS_HELP_STRING([--enable-eap-sim],[build SIM authenication module for EAP (default is NO).]),
@@ -311,6 +433,15 @@ AC_ARG_ENABLE(
 )
 AM_CONDITIONAL(USE_UML, test x$uml = xtrue)
 
+AC_ARG_ENABLE(
+    [fast],
+    AS_HELP_STRING([--enable-fast],[build libfast (FastCGI Application Server w/ templates (default is NO).]),
+    [if test x$enableval = xyes; then
+        fast=true
+    fi]
+)
+AM_CONDITIONAL(USE_FAST, test x$fast = xtrue)
+
 AC_ARG_ENABLE(
     [manager],
     AS_HELP_STRING([--enable-manager],[build web management console (default is NO).]),
@@ -409,7 +540,10 @@ dnl ==========================
 dnl  check required libraries
 dnl ==========================
 
+AC_HAVE_LIBRARY(dl)
+
 AC_CHECK_FUNCS(backtrace)
+AC_CHECK_FUNCS(dladdr)
 AC_CHECK_FUNCS(getifaddrs)
 
 AC_HAVE_LIBRARY([gmp],[LIBS="$LIBS"],[AC_MSG_ERROR([GNU Multi Precision library gmp not found])])      
@@ -417,8 +551,8 @@ if test "$ldap" = "true"; then
     AC_HAVE_LIBRARY([ldap],[LIBS="$LIBS"],[AC_MSG_ERROR([LDAP enabled, but library ldap not found])])
     AC_HAVE_LIBRARY([lber],[LIBS="$LIBS"],[AC_MSG_ERROR([LDAP enabled, but library lber not found])])
 fi
-if test "$http" = "true"; then
-    AC_HAVE_LIBRARY([curl],[LIBS="$LIBS"],[AC_MSG_ERROR([HTTP enabled, but library curl not found])])
+if test "$curl" = "true"; then
+    AC_HAVE_LIBRARY([curl],[LIBS="$LIBS"],[AC_MSG_ERROR([CURL enabled, but library curl not found])])
 fi
 
 if test "$xml" = "true"; then
@@ -460,8 +594,8 @@ AC_TRY_COMPILE(
 if test "$ldap" = "true"; then
     AC_CHECK_HEADER([ldap.h],,[AC_MSG_ERROR([LDAP enabled, but ldap.h not found!])])
 fi
-if test "$http" = "true"; then
-    AC_CHECK_HEADER([curl/curl.h],,[AC_MSG_ERROR([HTTP enabled, but curl.h not found!])])
+if test "$curl" = "true"; then
+    AC_CHECK_HEADER([curl/curl.h],,[AC_MSG_ERROR([CURL enabled, but curl.h not found!])])
 fi
 
 dnl ==============================
@@ -473,11 +607,34 @@ AC_OUTPUT(
        src/Makefile
        src/include/Makefile
        src/libstrongswan/Makefile
+       src/libstrongswan/plugins/aes/Makefile
+       src/libstrongswan/plugins/des/Makefile
+       src/libstrongswan/plugins/md5/Makefile
+       src/libstrongswan/plugins/sha1/Makefile
+       src/libstrongswan/plugins/sha2/Makefile
+       src/libstrongswan/plugins/fips_prf/Makefile
+       src/libstrongswan/plugins/gmp/Makefile
+       src/libstrongswan/plugins/hmac/Makefile
+       src/libstrongswan/plugins/x509/Makefile
+       src/libstrongswan/plugins/curl/Makefile
+       src/libstrongswan/plugins/ldap/Makefile
+       src/libstrongswan/plugins/mysql/Makefile
+       src/libstrongswan/plugins/sqlite/Makefile
        src/libcrypto/Makefile
        src/libfreeswan/Makefile
        src/pluto/Makefile
        src/whack/Makefile
        src/charon/Makefile
+       src/charon/plugins/eap_aka/Makefile
+       src/charon/plugins/eap_identity/Makefile
+       src/charon/plugins/eap_md5/Makefile
+       src/charon/plugins/eap_sim/Makefile
+       src/charon/plugins/dbus/Makefile
+       src/charon/plugins/xml/Makefile
+       src/charon/plugins/sql/Makefile
+       src/charon/plugins/med_db/Makefile
+       src/charon/plugins/stroke/Makefile
+       src/charon/plugins/unit_tester/Makefile
        src/stroke/Makefile
        src/ipsec/Makefile
        src/starter/Makefile
@@ -487,6 +644,7 @@ AC_OUTPUT(
        src/openac/Makefile
        src/scepclient/Makefile
        src/dumm/Makefile
+       src/libfast/Makefile
        src/manager/Makefile
        testing/Makefile
 )
index 2b7d42c132c405ee6406494d65abadeab9b77750..14b3444cda99750b796c2ba359bcb90f93a182da 100755 (executable)
@@ -1,4 +1,4 @@
 #!/bin/bash
 CFLAGS="-Wall -Wno-format -Wno-pointer-sign -Wno-strict-aliasing -g -O2" ./configure \
---sysconfdir=/etc --with-random-device=/dev/urandom \
---enable-leak-detective
+--sysconfdir=/etc --disable-tools --disable-pluto --enable-leak-detective --with-random-device=/dev/urandom \
+$1 $2 $3 $4 $5
index 4c8ed7d7ebdc69f276ecfc136e7a2fe2d93ef8c2..5044012301d106bb5a5ec4dd291373fbce500e2b 100644 (file)
@@ -31,6 +31,10 @@ if USE_UML
   SUBDIRS += dumm
 endif
 
+if USE_FAST
+  SUBDIRS += libfast
+endif
+
 if USE_MANAGER
   SUBDIRS += manager
 endif
index 1d702233649a254e614697f784a545de7fd2e41d..0ee61cd087560638b570db0ef7402f86577188e0 100644 (file)
@@ -4,16 +4,13 @@ charon_SOURCES = \
 bus/bus.c bus/bus.h \
 bus/listeners/file_logger.c bus/listeners/file_logger.h \
 bus/listeners/sys_logger.c bus/listeners/sys_logger.h \
-config/backends/backend.h config/backends/writeable_backend.h \
-config/backend_manager.c config/backend_manager.h \
+config/backend_manager.c config/backend_manager.h config/backend.h \
 config/child_cfg.c config/child_cfg.h \
-config/credentials/local_credential_store.c config/credentials/local_credential_store.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 \
-control/interfaces/interface.h \
-control/interface_manager.c control/interface_manager.h \
+control/controller.c control/controller.h \
 daemon.c daemon.h \
 encoding/generator.c encoding/generator.h \
 encoding/message.c encoding/message.h \
@@ -63,6 +60,7 @@ processing/processor.c processing/processor.h  \
 sa/authenticators/authenticator.c sa/authenticators/authenticator.h \
 sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \
 sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \
+sa/authenticators/eap/eap_manager.c sa/authenticators/eap/eap_manager.h \
 sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \
 sa/authenticators/rsa_authenticator.c sa/authenticators/rsa_authenticator.h \
 sa/child_sa.c sa/child_sa.h \
@@ -74,7 +72,8 @@ 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.c sa/tasks/ike_cert.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 \
 sa/tasks/ike_delete.c sa/tasks/ike_delete.h \
 sa/tasks/ike_dpd.c sa/tasks/ike_dpd.h \
@@ -84,7 +83,10 @@ sa/tasks/ike_mobike.c sa/tasks/ike_mobike.h \
 sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
 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
+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/credential_set.h
 
 # Use RAW socket if pluto gets built
 if USE_PLUTO
@@ -102,89 +104,53 @@ if USE_P2P
     sa/tasks/ike_p2p.c sa/tasks/ike_p2p.h
 endif
 
-INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke
-AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \
-       -DIPSEC_EAPDIR=\"${eapdir}\" -DIPSEC_BACKENDDIR=\"${backenddir}\" -DIPSEC_INTERFACEDIR=\"${interfacedir}\" \
-       -DSIM_READER_LIB=\"${simreader}\"
-charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lgmp -lpthread -lm -ldl
-
-if USE_LIBCURL
-  charon_LDADD += -lcurl
-endif
+INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+AM_CFLAGS = -rdynamic -DIPSEC_DIR=\"${ipsecdir}\" \
+       -DIPSEC_PIDDIR=\"${piddir}\" -DIPSEC_PLUGINDIR=\"${plugindir}\"
+charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lm -ldl
 
+# build optional plugins
+########################
 
-# build EAP plugins
-###################
-eap_LTLIBRARIES =
+SUBDIRS = 
 
-if USE_EAP_IDENTITY
-  eap_LTLIBRARIES += libcharon-eapidentity.la
-  libcharon_eapidentity_la_SOURCES = sa/authenticators/eap/eap_identity.h sa/authenticators/eap/eap_identity.c
-  libcharon_eapidentity_la_LDFLAGS = -module
+if USE_UNIT_TESTS
+  SUBDIRS += plugins/unit_tester
 endif
 
-if USE_EAP_SIM
-  eap_LTLIBRARIES += libcharon-eapsim.la
-  libcharon_eapsim_la_SOURCES = sa/authenticators/eap/eap_sim.h sa/authenticators/eap/eap_sim.c
-  libcharon_eapsim_la_LDFLAGS = -module
-
-  plugin_LTLIBRARIES = libcharon-eapsim-file.la
-  libcharon_eapsim_file_la_SOURCES = sa/authenticators/eap/sim/eap_sim_file.c
-  libcharon_eapsim_file_la_LDFLAGS = -module
+if USE_STROKE
+  SUBDIRS += plugins/stroke
 endif
 
-if USE_EAP_MD5
-  eap_LTLIBRARIES += libcharon-eapmd5.la
-  libcharon_eapmd5_la_SOURCES = sa/authenticators/eap/eap_md5.h sa/authenticators/eap/eap_md5.c
-  libcharon_eapmd5_la_LDFLAGS = -module
+if USE_LIBDBUS
+  SUBDIRS += plugins/dbus
 endif
 
-if USE_EAP_AKA
-  eap_LTLIBRARIES += libcharon-eapaka.la
-  libcharon_eapaka_la_SOURCES = sa/authenticators/eap/eap_aka.h sa/authenticators/eap/eap_aka.c
-  libcharon_eapaka_la_LDFLAGS = -module
+if USE_LIBXML
+  SUBDIRS += plugins/xml
 endif
 
-# build backends
-################
-backend_LTLIBRARIES =
-
-if USE_STROKE
-  backend_LTLIBRARIES += libcharon-local.la
-  libcharon_local_la_SOURCES = config/backends/local_backend.h config/backends/local_backend.c
-  libcharon_local_la_LDFLAGS = -module
+if USE_SQL
+  SUBDIRS += plugins/sql
 endif
 
-if USE_LIBSQLITE
-  backend_LTLIBRARIES += libcharon-sqlite.la
-  libcharon_sqlite_la_SOURCES = config/backends/sqlite_backend.h config/backends/sqlite_backend.c
-  libcharon_sqlite_la_LIBADD = -lsqlite3
-  libcharon_sqlite_la_LDFLAGS = -module
+if USE_EAP_IDENTITY
+  SUBDIRS += plugins/eap_identity
 endif
 
-# build control interfaces
-##########################
-interface_LTLIBRARIES =
+if USE_EAP_SIM
+  SUBDIRS += plugins/eap_sim
+endif
 
-if USE_STROKE
-  interface_LTLIBRARIES += libcharon-stroke.la
-  libcharon_stroke_la_SOURCES = control/interfaces/stroke_interface.h control/interfaces/stroke_interface.c
-  libcharon_stroke_la_LDFLAGS = -module
+if USE_EAP_MD5
+  SUBDIRS += plugins/eap_md5
 endif
 
-if USE_LIBDBUS
-  interface_LTLIBRARIES += libcharon-dbus.la
-  libcharon_dbus_la_SOURCES = control/interfaces/dbus_interface.h control/interfaces/dbus_interface.c
-  libcharon_dbus_la_LDFLAGS = -module
-  libcharon_dbus_la_LIBADD = ${dbus_LIBS}
-  INCLUDES += ${dbus_CFLAGS}
+if USE_EAP_AKA
+  SUBDIRS += plugins/eap_aka
 endif
 
-if USE_LIBXML
-  interface_LTLIBRARIES += libcharon-xml.la
-  libcharon_xml_la_SOURCES = control/interfaces/xml_interface.h control/interfaces/xml_interface.c
-  libcharon_xml_la_LDFLAGS = -module
-  libcharon_xml_la_LIBADD = ${xml_LIBS}
-  INCLUDES += ${xml_CFLAGS}
+if USE_MED_DB
+  SUBDIRS += plugins/med_db
 endif
 
index e53ac43cedc9263055b6ffdbbc9d2e5afece542e..5f813e7815fce0772aac238bfb1bf960ce65e3bf 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file bus.c
- *
- * @brief Implementation of bus_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "bus.h"
@@ -25,6 +20,7 @@
 #include <pthread.h>
 
 #include <daemon.h>
+#include <utils/mutex.h>
 
 ENUM(signal_names, SIG_ANY, SIG_MAX,
        /** should not get printed */
@@ -72,9 +68,9 @@ struct private_bus_t {
        linked_list_t *listeners;
        
        /**
-        * mutex to synchronize active listeners
+        * mutex to synchronize active listeners, recursively
         */
-       pthread_mutex_t mutex;
+       mutex_t *mutex;
        
        /**
         * Thread local storage for a unique, simple thread ID
@@ -107,7 +103,7 @@ struct entry_t {
        /**
         * condvar where active listeners wait
         */
-       pthread_cond_t cond;
+       condvar_t *condvar;
 };
 
 /**
@@ -119,11 +115,20 @@ static entry_t *entry_create(bus_listener_t *listener, bool blocker)
        
        this->listener = listener;
        this->blocker = blocker;
-       pthread_cond_init(&this->cond, NULL);
+       this->condvar = condvar_create(CONDVAR_DEFAULT);
        
        return this;
 }
 
+/**
+ * destroy an entry_t
+ */
+static void entry_destroy(entry_t *entry)
+{
+       entry->condvar->destroy(entry->condvar);
+       free(entry);
+}
+
 /**
  * Get a unique thread number for a calling thread. Since
  * pthread_self returns large and ugly numbers, use this function
@@ -151,9 +156,9 @@ static int get_thread_number(private_bus_t *this)
  */
 static void add_listener(private_bus_t *this, bus_listener_t *listener)
 {
-       pthread_mutex_lock(&this->mutex);
+       this->mutex->lock(this->mutex);
        this->listeners->insert_last(this->listeners, entry_create(listener, FALSE));
-       pthread_mutex_unlock(&this->mutex);
+       this->mutex->unlock(this->mutex);
 }
 
 /**
@@ -164,19 +169,19 @@ static void remove_listener(private_bus_t *this, bus_listener_t *listener)
        iterator_t *iterator;
        entry_t *entry;
 
-       pthread_mutex_lock(&this->mutex);
+       this->mutex->lock(this->mutex);
        iterator = this->listeners->create_iterator(this->listeners, TRUE);
        while (iterator->iterate(iterator, (void**)&entry))
        {
                if (entry->listener == listener)
                {
                        iterator->remove(iterator);
-                       free(entry);
+                       entry_destroy(entry);
                        break;
                }
        }
        iterator->destroy(iterator);
-       pthread_mutex_unlock(&this->mutex);
+       this->mutex->unlock(this->mutex);
 }
 
 typedef struct cleanup_data_t cleanup_data_t;
@@ -205,7 +210,7 @@ static void listener_cleanup(cleanup_data_t *data)
                if (entry == data->entry)
                {
                        iterator->remove(iterator);
-                       free(entry);
+                       entry_destroy(entry);
                        break;
                }
        }
@@ -223,21 +228,21 @@ static void listen_(private_bus_t *this, bus_listener_t *listener, job_t *job)
        data.this = this;
        data.entry = entry_create(listener, TRUE);
 
-       pthread_mutex_lock(&this->mutex);
+       this->mutex->lock(this->mutex);
        this->listeners->insert_last(this->listeners, data.entry);
        charon->processor->queue_job(charon->processor, job);
-       pthread_cleanup_push((void*)pthread_mutex_unlock, &this->mutex);
+       pthread_cleanup_push((void*)this->mutex->unlock, this->mutex);
        pthread_cleanup_push((void*)listener_cleanup, &data);
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
        while (data.entry->blocker)
        {
-               pthread_cond_wait(&data.entry->cond, &this->mutex);
+               data.entry->condvar->wait(data.entry->condvar, this->mutex);
        }
        pthread_setcancelstate(old, NULL);
        pthread_cleanup_pop(FALSE);
        /* unlock mutex */
        pthread_cleanup_pop(TRUE);
-       free(data.entry);
+       entry_destroy(data.entry);
 }
 
 /**
@@ -248,6 +253,7 @@ static void set_sa(private_bus_t *this, ike_sa_t *ike_sa)
        pthread_setspecific(this->thread_sa, ike_sa);
 }
 
+       
 /**
  * Implementation of bus_t.vsignal.
  */
@@ -259,7 +265,7 @@ static void vsignal(private_bus_t *this, signal_t signal, level_t level,
        ike_sa_t *ike_sa;
        long thread;
        
-       pthread_mutex_lock(&this->mutex);
+       this->mutex->lock(this->mutex);
        ike_sa = pthread_getspecific(this->thread_sa);
        thread = get_thread_number(this);
        
@@ -275,18 +281,18 @@ static void vsignal(private_bus_t *this, signal_t signal, level_t level,
                        if (entry->blocker)
                        {
                                entry->blocker = FALSE;
-                               pthread_cond_signal(&entry->cond);
+                               entry->condvar->signal(entry->condvar);
                        }
                        else
                        {
-                               free(entry);
+                               entry_destroy(entry);
                        }
                }
                va_end(args_copy);
        }
        iterator->destroy(iterator);
        
-       pthread_mutex_unlock(&this->mutex);
+       this->mutex->unlock(this->mutex);
 }
 
 /**
@@ -307,7 +313,8 @@ static void signal_(private_bus_t *this, signal_t signal, level_t level,
  */
 static void destroy(private_bus_t *this)
 {
-       this->listeners->destroy_function(this->listeners, free);
+       this->mutex->destroy(this->mutex);
+       this->listeners->destroy_function(this->listeners, (void*)entry_destroy);
        free(this);
 }
 
@@ -327,7 +334,7 @@ bus_t *bus_create()
        this->public.destroy = (void(*)(bus_t*)) destroy;
        
        this->listeners = linked_list_create();
-       pthread_mutex_init(&this->mutex, NULL);
+       this->mutex = mutex_create(MUTEX_DEFAULT);
        pthread_key_create(&this->thread_id, NULL);
        pthread_key_create(&this->thread_sa, NULL);
        
index f71018444dac4292ccc0089f3db43f9faed29c4c..678bf37d4ad326478f59162b0d1cea8d27db7b40 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file bus.h
- *
- * @brief Interface of bus_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 bus bus
+ * @{ @ingroup charon
  */
 
 #ifndef BUS_H_
@@ -36,7 +36,7 @@ typedef struct bus_t bus_t;
 
 
 /**
- * @brief signals emitted by the daemon.
+ * signals emitted by the daemon.
  *
  * Signaling is for different purporses. First, it allows debugging via
  * "debugging signal messages", sencondly, it allows to follow certain
@@ -52,8 +52,6 @@ typedef struct bus_t bus_t;
  * Debug signal betwee a START and a SUCCESS/FAILED belongs to that operation
  * if the IKE_SA is the same. The thread may change, as multiple threads
  * may be involved in a complex scenario.
- *
- * @ingroup bus
  */
 enum signal_t {
        /** pseudo signal, representing any other signal */
@@ -157,7 +155,7 @@ enum level_t {
 
 #if DEBUG_LEVEL >= 1
 /**
- * @brief Log a debug message via the signal bus.
+ * Log a debug message via the signal bus.
  *
  * @param signal       signal_t signal description
  * @param format       printf() style format string
@@ -189,7 +187,7 @@ enum level_t {
 #endif /* DBG4 */
 
 /**
- * @brief Raise a signal for an occured event.
+ * Raise a signal for an occured event.
  *
  * @param sig          signal_t signal description
  * @param format       printf() style format string
@@ -198,7 +196,7 @@ enum level_t {
 #define SIG(sig, format, ...) charon->bus->signal(charon->bus, sig, LEVEL_0, format, ##__VA_ARGS__)
 
 /**
- * @brief Get the type of a signal.
+ * Get the type of a signal.
  *
  * A signal may be a debugging signal with a specific context. They have
  * a level specific for their context > 0. All audit signals use the
@@ -211,17 +209,15 @@ enum level_t {
 
 
 /**
- * @brief Interface for registering at the signal bus.
+ * Interface for registering at the signal bus.
  *
  * To receive signals from the bus, the client implementing the
  * bus_listener_t interface registers itself at the signal bus.
- *
- * @ingroup bus
  */
 struct bus_listener_t {
        
        /**
-        * @brief Send a signal to a bus listener.
+        * Send a signal to a bus listener.
         *
         * A numerical identification for the thread is included, as the
         * associated IKE_SA, if any. Signal specifies the type of
@@ -231,8 +227,10 @@ struct bus_listener_t {
         * a "..." parameters to functions is not (cleanly) possible.
         * The implementing signal function returns TRUE to stay registered
         * to the bus, or FALSE to unregister itself.
+        * You should not call bus_t.signal() inside of a registered listener,
+        * as it WILL call itself recursively. If you do so, make shure to 
+        * avoid infinite recursion. Watch your stack!
         *
-        * @param this          listener
         * @param singal        kind of the signal (up, down, rekeyed, ...)
         * @param level         verbosity level of the signal
         * @param thread        ID of the thread raised this signal
@@ -246,40 +244,36 @@ struct bus_listener_t {
 };
 
 /**
- * @brief Signal bus which sends signals to registered listeners.
+ * Signal bus which sends signals to registered listeners.
  *
  * The signal bus is not much more than a multiplexer. A listener interested
  * in receiving event signals registers at the bus. Any signals sent to
  * are delivered to all registered listeners.
  * To deliver signals to threads, the blocking listen() call may be used
  * to wait for a signal.
- *
- * @ingroup bus
  */
 struct bus_t {
        
        /**
-        * @brief Register a listener to the bus.
+        * Register a listener to the bus.
         *
         * A registered listener receives all signals which are sent to the bus.
         * The listener is passive; the thread which emitted the signal
         * processes the listener routine.
         *
-        * @param this          bus
         * @param listener      listener to register.
         */
        void (*add_listener) (bus_t *this, bus_listener_t *listener);
        
        /**
-        * @brief Unregister a listener from the bus.
+        * Unregister a listener from the bus.
         *
-        * @param this          bus
         * @param listener      listener to unregister.
         */
        void (*remove_listener) (bus_t *this, bus_listener_t *listener);
        
        /**
-        * @brief Register a listener and block the calling thread.
+        * Register a listener and block the calling thread.
         *
         * This call registers a listener and blocks the calling thread until
         * its listeners function returns FALSE. This allows to wait for certain
@@ -287,14 +281,13 @@ struct bus_t {
         * registered, this allows to listen on events we initiate with the job
         * without missing any signals.
         *
-        * @param this          bus
         * @param listener      listener to register
         * @param job           job to execute asynchronously when registered, or NULL
         */
        void (*listen)(bus_t *this, bus_listener_t *listener, job_t *job);
        
        /**
-        * @brief Set the IKE_SA the calling thread is using.
+        * Set the IKE_SA the calling thread is using.
         *
         * To associate an received signal to an IKE_SA without passing it as
         * parameter each time, the thread registers it's used IKE_SA each
@@ -302,13 +295,12 @@ struct bus_t {
         * the IKE_SA (by passing NULL). This IKE_SA is stored per-thread, so each
         * thread has one IKE_SA registered (or not).
         * 
-        * @param this          bus
         * @param ike_sa        ike_sa to register, or NULL to unregister
         */
        void (*set_sa) (bus_t *this, ike_sa_t *ike_sa);
        
        /**
-        * @brief Send a signal to the bus.
+        * Send a signal to the bus.
         *
         * The signal specifies the type of the event occured. The format string
         * specifies an additional informational or error message with a
@@ -316,7 +308,6 @@ struct bus_t {
         * Some useful macros are available to shorten this call.
         * @see SIG(), DBG1()
         *
-        * @param this          bus
         * @param singal        kind of the signal (up, down, rekeyed, ...)
         * @param level         verbosity level of the signal
         * @param format        printf() style format string
@@ -325,7 +316,7 @@ struct bus_t {
        void (*signal) (bus_t *this, signal_t signal, level_t level, char* format, ...);
        
        /**
-        * @brief Send a signal to the bus using va_list arguments.
+        * Send a signal to the bus using va_list arguments.
         *
         * Same as bus_t.signal(), but uses va_list argument list.
         *
@@ -333,7 +324,6 @@ struct bus_t {
         * called extensively and therefore shouldn't allocate heap memory or
         * do other expensive tasks!
         *
-        * @param this          bus
         * @param singal        kind of the signal (up, down, rekeyed, ...)
         * @param level         verbosity level of the signal
         * @param format        printf() style format string
@@ -342,20 +332,16 @@ struct bus_t {
        void (*vsignal) (bus_t *this, signal_t signal, level_t level, char* format, va_list args);
        
        /**
-        * @brief Destroy the signal bus.
-        *
-        * @param this          bus to destroy
+        * Destroy the signal bus.
         */
        void (*destroy) (bus_t *this);
 };
 
 /**
- * @brief Create the signal bus which multiplexes signals to its listeners.
+ * Create the signal bus which multiplexes signals to its listeners.
  *
  * @return             signal bus instance
- * 
- * @ingroup bus
  */
 bus_t *bus_create();
 
-#endif /* BUS_H_ */
+#endif /* BUS_H_ @} */
index 14f9f72cf3e10ce3f35f0c26771587152f054d84..1a31e316ea26d50d1eb37d94d05d397ffd17df95 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file file_logger.c
- *
- * @brief Implementation of file_logger_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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>
index d67daba25beb7ac8348fc01875171334afc49af4..6b716c6a7e2e36f7da46a5837ef07bfe367d61d7 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file file_logger.h
- *
- * @brief Interface of file_logger_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 file_logger file_logger
+ * @{ @ingroup listeners
  */
 
 #ifndef FILE_LOGGER_H_
@@ -28,12 +28,7 @@ typedef struct file_logger_t file_logger_t;
 #include <bus/bus.h>
 
 /**
- * @brief Logger to files which implements bus_listener_t.
- *
- * @b Constructors:
- *  - file_logger_create()
- *
- * @ingroup listeners
+ * Logger to files which implements bus_listener_t.
  */
 struct file_logger_t {
        
@@ -43,31 +38,25 @@ struct file_logger_t {
        bus_listener_t listener;
        
        /**
-        * @brief Set the loglevel for a signal type.
+        * Set the loglevel for a signal type.
         *
-        * @param this          stream_logger_t object
         * @param singal        type of signal
         * @param level         max level to log (0..4)
         */
        void (*set_level) (file_logger_t *this, signal_t signal, level_t level);
        
        /**
-        * @brief Destroys a file_logger_t object.
-        *
-        * @param this          file_logger_t object
+        * Destroys a file_logger_t object.
         */
        void (*destroy) (file_logger_t *this);
 };
 
 /**
- * @brief Constructor to create a file_logger_t object.
+ * Constructor to create a file_logger_t object.
  *
  * @param out          FILE to write to
  * @return                     file_logger_t object
- *
- * @ingroup listeners
  */
 file_logger_t *file_logger_create(FILE *out);
 
-
-#endif /* FILE_LOGGER_H_ */
+#endif /* FILE_LOGGER_H_ @} */
index d26d14dc00356d9d27c1fd0e542a6ffa5e9cb6e2..876fab8fdf3e26aa6f013b48ab25b4eb4c807f84 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file sys_logger.c
- *
- * @brief Implementation of sys_logger_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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>
index 091217313d34c11870ae70a6418f9062ca154515..1a04c2ad9a0d1aae7615e8ec5e84c88dede745af 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file sys_logger.h
- *
- * @brief Interface of sys_logger_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 sys_logger sys_logger
+ * @{ @ingroup listeners
  */
 
 #ifndef SYS_LOGGER_H_
@@ -30,12 +30,7 @@ typedef struct sys_logger_t sys_logger_t;
 #include <bus/bus.h>
 
 /**
- * @brief Logger for syslog which implements bus_listener_t.
- *
- * @b Constructors:
- *  - sys_logger_create()
- *
- * @ingroup listeners
+ * Logger for syslog which implements bus_listener_t.
  */
 struct sys_logger_t {
        
@@ -45,31 +40,25 @@ struct sys_logger_t {
        bus_listener_t listener;
        
        /**
-        * @brief Set the loglevel for a signal type.
+        * Set the loglevel for a signal type.
         *
-        * @param this          stream_logger_t object
         * @param singal        type of signal
         * @param level         max level to log
         */
        void (*set_level) (sys_logger_t *this, signal_t signal, level_t level);
        
        /**
-        * @brief Destroys a sys_logger_t object.
-        *
-        * @param this          sys_logger_t object
+        * Destroys a sys_logger_t object.
         */
        void (*destroy) (sys_logger_t *this);
 };
 
 /**
- * @brief Constructor to create a sys_logger_t object.
+ * Constructor to create a sys_logger_t object.
  *
  * @param facility     syslog facility to use
  * @return                     sys_logger_t object
- *
- * @ingroup listeners
  */
 sys_logger_t *sys_logger_create(int facility);
 
-
-#endif /* SYS_LOGGER_H_ */
+#endif /* SYS_LOGGER_H_ @} */
diff --git a/src/charon/config/backend.h b/src/charon/config/backend.h
new file mode 100644 (file)
index 0000000..96e76e0
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007-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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup backend backend
+ * @{ @ingroup config
+ */
+
+#ifndef BACKEND_H_
+#define BACKEND_H_
+
+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>
+
+/**
+ * The interface for a configuration backend.
+ *
+ * A configuration backend is loaded into the backend_manager. It does the actual
+ * configuration lookup for the method it implements. See backend_manager_t for
+ * more information.
+ */
+struct backend_t {
+
+       /**
+        * Create an enumerator over all IKE configs matching two hosts.
+        *
+        * Hosts may be NULL to get all.
+        *
+        * @param me            address of local host
+        * @param other         address of remote host
+        * @return                      enumerator over ike_cfg_t's
+        */
+       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.
+        *
+        * IDs may be NULL to get all.
+        *
+        * @param me            identity of ourself
+        * @param other         identity of remote host
+        * @return                      enumerator over peer_cfg_t
+        */
+       enumerator_t* (*create_peer_cfg_enumerator)(backend_t *this,
+                                                                                               identification_t *me,
+                                                                                               identification_t *other);
+       /**
+        * Get a peer_cfg identified by it's name, or a name of its child.
+        *
+        * @param name                          name of peer/child cfg
+        * @return                                      matching peer_config, or NULL if none found
+        */
+       peer_cfg_t *(*get_peer_cfg_by_name)(backend_t *this, char *name);
+};
+
+#endif /* BACKEND_H_ @} */
index b2104aceaaeb51a0f68a52c29114530478ee4187..075ab24177b78113dd7b13602374ddef195da2ed 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file backend_manager.c
- * 
- * @brief Implementation of backend_manager_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 "backend_manager.h"
 
 #include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <dlfcn.h>
+#include <pthread.h>
 
 #include <daemon.h>
 #include <utils/linked_list.h>
-#include <config/backends/writeable_backend.h>
+#include <utils/mutex.h>
 
 
 typedef struct private_backend_manager_t private_backend_manager_t;
@@ -50,164 +43,249 @@ struct private_backend_manager_t {
        linked_list_t *backends;
        
        /**
-        * Additional list of writable backends.
-        */
-       linked_list_t *writeable;
-       
-       /**
-        * List of dlopen() handles we used to open backends
+        * locking mutex
         */
-       linked_list_t *handles;
+       mutex_t *mutex;
 };
 
 /**
- * implements backend_manager_t.get_ike_cfg.
+ * data to pass nested IKE enumerator
  */
-static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this, 
-                                                         host_t *my_host, host_t *other_host)
+typedef struct {
+       private_backend_manager_t *this;
+       host_t *me;
+       host_t *other;
+} 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;
+
+/**
+ * destroy IKE enumerator data and unlock list
+ */
+static void ike_enum_destroy(ike_data_t *data)
 {
-       backend_t *backend;
-       ike_cfg_t *config = NULL;
-       iterator_t *iterator = this->backends->create_iterator(this->backends, TRUE);
-       while (config == NULL && iterator->iterate(iterator, (void**)&backend))
-       {
-               config = backend->get_ike_cfg(backend, my_host, other_host);
-       }
-       iterator->destroy(iterator);
-       return config;
+       data->this->mutex->unlock(data->this->mutex);
+       free(data);
 }
 
 /**
- * implements backend_manager_t.get_peer_cfg.
- */                    
-static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this,
-                                                               identification_t *my_id, identification_t *other_id,
-                                                               ca_info_t *other_ca_info)
+ * destroy PEER enumerator data and unlock list
+ */
+static void peer_enum_destroy(peer_data_t *data)
 {
-       backend_t *backend;
-       peer_cfg_t *config = NULL;
-       iterator_t *iterator = this->backends->create_iterator(this->backends, TRUE);
-       while (config == NULL && iterator->iterate(iterator, (void**)&backend))
-       {
-               config = backend->get_peer_cfg(backend, my_id, other_id, other_ca_info);
-       }
-       iterator->destroy(iterator);
-       return config;
+       data->this->mutex->unlock(data->this->mutex);
+       free(data);
 }
 
 /**
- * implements backend_manager_t.get_peer_cfg_by_name.
- */                    
-static peer_cfg_t *get_peer_cfg_by_name(private_backend_manager_t *this, char *name)
+ * inner enumerator constructor for IKE cfgs
+ */
+static enumerator_t *ike_enum_create(backend_t *backend, ike_data_t *data)
 {
-       backend_t *backend;
-       peer_cfg_t *config = NULL;
-       iterator_t *iterator = this->backends->create_iterator(this->backends, TRUE);
-       while (config == NULL && iterator->iterate(iterator, (void**)&backend))
-       {
-               config = backend->get_peer_cfg_by_name(backend, name);
-       }
-       iterator->destroy(iterator);
-       return config;
+       return backend->create_ike_cfg_enumerator(backend, data->me, data->other);
 }
 
 /**
- * implements backend_manager_t.add_peer_cfg.
- */    
-static void add_peer_cfg(private_backend_manager_t *this, peer_cfg_t *config)
+ * inner enumerator constructor for Peer cfgs
+ */
+static enumerator_t *peer_enum_create(backend_t *backend, peer_data_t *data)
 {
-       writeable_backend_t *backend;
-       
-       if (this->writeable->get_first(this->writeable, (void**)&backend) == SUCCESS)
-       {
-               backend->add_cfg(backend, config);
-       }
+       return backend->create_peer_cfg_enumerator(backend, data->me, data->other);
 }
-
 /**
- * implements backend_manager_t.create_iterator.
- */    
-static iterator_t* create_iterator(private_backend_manager_t *this)
+ * inner enumerator constructor for all Peer cfgs
+ */
+static enumerator_t *peer_enum_create_all(backend_t *backend)
 {
-       writeable_backend_t *backend;
-       
-       if (this->writeable->get_first(this->writeable, (void**)&backend) == SUCCESS)
-       {
-               return backend->create_iterator(backend);
-       }
-       /* give out an empty iterator if we have no writable backend*/
-       return this->writeable->create_iterator(this->writeable, TRUE);
+       return backend->create_peer_cfg_enumerator(backend, NULL, NULL);
 }
 
 /**
- * load the configuration backend modules
+ * implements backend_manager_t.get_ike_cfg.
  */
-static void load_backends(private_backend_manager_t *this)
+static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this, 
+                                                         host_t *me, host_t *other)
 {
-       struct dirent* entry;
-       DIR* dir;
-
-       dir = opendir(IPSEC_BACKENDDIR);
-       if (dir == NULL)
-       {
-               DBG1(DBG_CFG, "error opening backend modules directory "IPSEC_BACKENDDIR);
-               return;
-       }
+       ike_cfg_t *current, *found = NULL;
+       enumerator_t *enumerator;
+       host_t *my_candidate, *other_candidate;
+       ike_data_t *data;
+       enum {
+               MATCH_NONE  = 0x00,
+               MATCH_ANY   = 0x01,
+               MATCH_ME    = 0x04,
+               MATCH_OTHER = 0x08,
+       } prio, best = MATCH_ANY;
        
-       DBG1(DBG_CFG, "loading backend modules from '"IPSEC_BACKENDDIR"'");
-
-       while ((entry = readdir(dir)) != NULL)
+       data = malloc_thing(ike_data_t);
+       data->this = this;
+       data->me = me;
+       data->other = other;
+       
+       DBG2(DBG_CFG, "looking for a config for %H...%H", me, other);
+       
+       this->mutex->lock(this->mutex);
+       enumerator = enumerator_create_nested(
+                                               this->backends->create_enumerator(this->backends),
+                                               (void*)ike_enum_create, data, (void*)ike_enum_destroy);
+       while (enumerator->enumerate(enumerator, (void**)&current))
        {
-               char file[256];
-               backend_t *backend;
-               backend_constructor_t constructor;
-               void *handle;
-               char *ending;
+               prio = MATCH_NONE;
+               my_candidate = current->get_my_host(current);
+               other_candidate = current->get_other_host(current);
                
-               snprintf(file, sizeof(file), IPSEC_BACKENDDIR"/%s", entry->d_name);
-               
-               ending = entry->d_name + strlen(entry->d_name) - 3;
-               if (ending <= entry->d_name || !streq(ending, ".so"))
+               if (my_candidate->ip_equals(my_candidate, me))
                {
-                       /* skip anything which does not look like a library */
-                       DBG2(DBG_CFG, "  skipping %s, doesn't look like a library",
-                                entry->d_name);
-                       continue;
+                       prio += MATCH_ME;
                }
-               /* try to load the library */
-               handle = dlopen(file, RTLD_LAZY);
-               if (handle == NULL)
+               else if (my_candidate->is_anyaddr(my_candidate))
                {
-                       DBG1(DBG_CFG, "  opening backend module %s failed: %s",
-                                entry->d_name, dlerror());
-                       continue;
+                       prio += MATCH_ANY;
                }
-               constructor = dlsym(handle, "backend_create");
-               if (constructor == NULL)
+               if (other_candidate->ip_equals(other_candidate, other))
                {
-                       DBG1(DBG_CFG, "  backend module %s has no backend_create() "
-                                "function, skipped", entry->d_name);
-                       dlclose(handle);
-                       continue;
+                       prio += MATCH_OTHER;
                }
+               else if (other_candidate->is_anyaddr(other_candidate))
+               {
+                       prio += MATCH_ANY;
+               }
+               
+               DBG2(DBG_CFG, "  candidate: %H...%H, prio %d",
+                        my_candidate, other_candidate, prio);
                
-               backend = constructor();
-               if (backend == NULL)
+               /* we require at least two MATCH_ANY */
+               if (prio > best)
                {
-                       DBG1(DBG_CFG, "  unable to create instance of backend "
-                                "module %s, skipped", entry->d_name);
-                       dlclose(handle);
-                       continue;
+                       best = prio;
+                       DESTROY_IF(found);
+                       found = current;
+                       found->get_ref(found);
                }
-               DBG1(DBG_CFG, "  loaded backend module successfully from %s", entry->d_name);
-               this->backends->insert_last(this->backends, backend);
-               if (backend->is_writeable(backend))
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return found;
+}
+
+
+static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this)
+{
+       this->mutex->lock(this->mutex);
+       return enumerator_create_nested(
+                                                       this->backends->create_enumerator(this->backends),
+                                                       (void*)peer_enum_create_all, this->mutex,
+                                                       (void*)this->mutex->unlock);
+}
+
+/**
+ * implements backend_manager_t.get_peer_cfg.
+ */                    
+static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this,
+                                                               identification_t *me, identification_t *other,
+                                                               auth_info_t *auth)
+{
+       peer_cfg_t *current, *found = NULL;
+       enumerator_t *enumerator;
+       identification_t *my_candidate, *other_candidate;
+       id_match_t best = ID_MATCH_NONE;
+       peer_data_t *data;
+       
+       DBG2(DBG_CFG, "looking for a config for %D...%D", me, other);
+       
+       data = malloc_thing(peer_data_t);
+       data->this = this;
+       data->me = me;
+       data->other = other;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = enumerator_create_nested(
+                                               this->backends->create_enumerator(this->backends),
+                                               (void*)peer_enum_create, data, (void*)peer_enum_destroy);
+       while (enumerator->enumerate(enumerator, &current))
+       {
+               id_match_t m1, m2, sum;
+
+               my_candidate = current->get_my_id(current);
+               other_candidate = current->get_other_id(current);
+               
+               m1 = my_candidate->matches(my_candidate, me);
+               m2 = other->matches(other, other_candidate);
+               sum = m1 + m2;
+               
+               if (m1 && m2)
                {
-                       this->writeable->insert_last(this->writeable, backend);
+                       if (auth->complies(auth, current->get_auth(current)))
+                       {
+                               DBG2(DBG_CFG, "  candidate '%s': %D...%D, prio %d",
+                                        current->get_name(current), my_candidate,
+                                        other_candidate, sum);
+                               if (sum > best)
+                               {
+                                       DESTROY_IF(found);
+                                       found = current;
+                                       found->get_ref(found);
+                                       best = sum;
+                               }
+                       }
                }
-               this->handles->insert_last(this->handles, handle);
        }
-       closedir(dir);
+       if (found)
+       {
+               DBG1(DBG_CFG, "found matching config \"%s\": %D...%D, prio %d",
+                        found->get_name(found), found->get_my_id(found),
+                        found->get_other_id(found), best);
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return found;
+}
+
+/**
+ * implements backend_manager_t.get_peer_cfg_by_name.
+ */                    
+static peer_cfg_t *get_peer_cfg_by_name(private_backend_manager_t *this, char *name)
+{
+       backend_t *backend;
+       peer_cfg_t *config = NULL;
+       enumerator_t *enumerator;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->backends->create_enumerator(this->backends);
+       while (config == NULL && enumerator->enumerate(enumerator, (void**)&backend))
+       {
+               config = backend->get_peer_cfg_by_name(backend, name);
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return config;
+}
+
+/**
+ * Implementation of backend_manager_t.remove_backend.
+ */
+static void remove_backend(private_backend_manager_t *this, backend_t *backend)
+{
+       this->mutex->lock(this->mutex);
+       this->backends->remove(this->backends, backend, NULL);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of backend_manager_t.add_backend.
+ */
+static void add_backend(private_backend_manager_t *this, backend_t *backend)
+{
+       this->mutex->lock(this->mutex);
+       this->backends->insert_last(this->backends, backend);
+       this->mutex->unlock(this->mutex);
 }
 
 /**
@@ -215,9 +293,8 @@ static void load_backends(private_backend_manager_t *this)
  */
 static void destroy(private_backend_manager_t *this)
 {
-       this->backends->destroy_offset(this->backends, offsetof(backend_t, destroy));
-       this->writeable->destroy(this->writeable);
-       this->handles->destroy_function(this->handles, (void*)dlclose);
+       this->backends->destroy(this->backends);
+       this->mutex->destroy(this->mutex);
        free(this);
 }
 
@@ -229,17 +306,15 @@ 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*,identification_t*,identification_t*,ca_info_t*))get_peer_cfg;
+       this->public.get_peer_cfg = (peer_cfg_t* (*)(backend_manager_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.add_peer_cfg = (void (*)(backend_manager_t*,peer_cfg_t*))add_peer_cfg;
-       this->public.create_iterator = (iterator_t* (*)(backend_manager_t*))create_iterator;
+       this->public.create_peer_cfg_enumerator = (enumerator_t* (*)(backend_manager_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;
        
        this->backends = linked_list_create();
-       this->writeable = linked_list_create();
-       this->handles = linked_list_create();
-       
-       load_backends(this);
+       this->mutex = mutex_create(MUTEX_RECURSIVE);
        
        return &this->public;
 }
index 7ca6d660e150f38dccdbc33fc2bc1af2a54f038e..a626d928f9749a32755ce8bd6a0a77e411501615 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file backend_manager.h
- * 
- * @brief Interface backend_manager_t.
- *  
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 backend_manager backend_manager
+ * @{ @ingroup config
  */
 
 #ifndef BACKEND_MANAGER_H_
@@ -30,20 +30,15 @@ typedef struct backend_manager_t backend_manager_t;
 #include <utils/identification.h>
 #include <config/ike_cfg.h>
 #include <config/peer_cfg.h>
-#include <config/backends/backend.h>
+#include <config/backend.h>
 
 
 /**
- * @brief A loader and multiplexer to use multiple backends.
+ * A loader and multiplexer to use multiple backends.
  *
  * Charon allows the use of multiple configuration backends simultaneously. To
  * access all this backends by a single call, this class wraps multiple
- * backends behind a single object. It is also responsible for loading
- * the backend modules and cleaning them up.
- * A backend may be writeable or not. All backends implement the backend_t
- * interface, those who are writeable additionally implement the
- * writeable_backend_t interface. Adding configs to the backend_manager will
- * be redirected to the first writeable backend.
+ * backends behind a single object.
  * @verbatim
 
    +---------+      +-----------+         +--------------+     |
@@ -55,18 +50,12 @@ typedef struct backend_manager_t backend_manager_t;
    +---------+      +-----------+                              |
    
    @endverbatim
- *
- * @b Constructors:
- * - backend_manager_create()
- * 
- * @ingroup config
  */
 struct backend_manager_t {
        
        /**
-        * @brief Get an ike_config identified by two hosts.
+        * Get an ike_config identified by two hosts.
         *
-        * @param this                          calling object
         * @param my_host                       address of own host
         * @param other_host            address of remote host
         * @return                                      matching ike_config, or NULL if none found
@@ -75,59 +64,57 @@ struct backend_manager_t {
                                                          host_t *my_host, host_t *other_host);
        
        /**
-        * @brief Get a peer_config identified by two IDs and the peer's certificate issuer
+        * Get a peer_config identified by two IDs and authorization info.
         *
-        * @param this                          calling object
         * @param my_id                         own ID
         * @param other_id                      peer ID
-        * @param other_ca_info         info record on issuer of peer certificate
+        * @param auth_info                     authorization info
         * @return                                      matching peer_config, or NULL if none found
         */
-       peer_cfg_t* (*get_peer_cfg)(backend_manager_t *this,
-                                                               identification_t *my_id, identification_t *other_id,
-                                                               ca_info_t *other_ca_info);
+       peer_cfg_t* (*get_peer_cfg)(backend_manager_t *this, identification_t *my_id,
+                                                               identification_t *other_id, auth_info_t *auth);
        
        /**
-        * @brief Get a peer_config identified by it's name.
+        * Get a peer_config identified by it's name.
         *
-        * @param this                          calling object
         * @param name                          name of the peer_config
         * @return                                      matching peer_config, or NULL if none found
         */
        peer_cfg_t* (*get_peer_cfg_by_name)(backend_manager_t *this, char *name);
        
        /**
-        * @brief Add a peer_config to the first found writable backend.
+        * Create an enumerator over all peer configs.
         *
-        * @param this          calling object
-        * @param config        peer_config to add to the backend
+        * @return                                      enumerator over peer configs
         */
-       void (*add_peer_cfg)(backend_manager_t *this, peer_cfg_t *config);
+       enumerator_t* (*create_peer_cfg_enumerator)(backend_manager_t *this);
        
        /**
-        * @brief Create an iterator over all peer configs of the writable backend.
+        * Register a backend on the manager.
         *
-        * @param this          calling object
-        * @return                      iterator over peer configs
+        * @param backend                       backend to register
         */
-       iterator_t* (*create_iterator)(backend_manager_t *this);
+       void (*add_backend)(backend_manager_t *this, backend_t *backend);
        
        /**
-        * @brief Destroys a backend_manager_t object.
+        * Unregister a backend.
         *
-        * @param this                                  calling object
+        * @param backend                       backend to unregister
+        */
+       void (*remove_backend)(backend_manager_t *this, backend_t *backend);
+       
+       /**
+        * Destroys a backend_manager_t object.
         */
        void (*destroy) (backend_manager_t *this);
 };
 
 /**
- * @brief Creates a new instance of the manager and loads all backends.
+ * Create an instance of the backend manager
  *
  * @return             backend_manager instance
- *
- * @ingroup config
  */
 backend_manager_t* backend_manager_create(void);
 
-#endif /*BACKEND_MANAGER_H_*/
+#endif /*BACKEND_MANAGER_H_ @} */
 
diff --git a/src/charon/config/backends/backend.h b/src/charon/config/backends/backend.h
deleted file mode 100644 (file)
index 592d1dd..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * @file backend.h
- * 
- * @brief Interface backend_t.
- *  
- */
-
-/*
- * 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.
- */
-
-#ifndef BACKEND_H_
-#define BACKEND_H_
-
-typedef struct backend_t backend_t;
-
-#include <library.h>
-#include <config/ike_cfg.h>
-#include <config/peer_cfg.h>
-#include <utils/linked_list.h>
-
-/**
- * @brief The interface for a configuration backend.
- *
- * A configuration backend is loaded by the backend_manager. It does the actual
- * configuration lookup for the method it implements. See backend_manager_t for
- * more information.
- *
- * @b Constructors:
- * - implementations constructors
- * 
- * @ingroup backends
- */
-struct backend_t {
-
-       /**
-        * @brief Get an ike_cfg identified by two hosts.
-        *
-        * @param this                          calling object
-        * @param my_host                       address of own host
-        * @param other_host            address of remote host
-        * @return                                      matching ike_config, or NULL if none found
-        */
-       ike_cfg_t *(*get_ike_cfg)(backend_t *this, 
-                                                         host_t *my_host, host_t *other_host);
-       
-       /**
-        * @brief Get a peer_cfg identified by two IDs.
-        * 
-        * Select a config based on the two IDs and the other's certificate issuer
-        *
-        * @param this                          calling object
-        * @param my_id                         own ID
-        * @param other_id                      peer ID
-        * @param other_ca_info         info record on issuer of peer certificate
-        * @return                                      matching peer_config, or NULL if none found
-        */
-       peer_cfg_t *(*get_peer_cfg)(backend_t *this,
-                                                               identification_t *my_id, identification_t *other_id,
-                                                               ca_info_t *other_ca_info);
-       
-       /**
-        * @brief Get a peer_cfg identified by it's name, or a name of its child.
-        *
-        * @param this                          calling object
-        * @param name                          
-        * @return                                      matching peer_config, or NULL if none found
-        */
-       peer_cfg_t *(*get_peer_cfg_by_name)(backend_t *this, char *name);
-       
-       /**
-        * @brief Check if a backend is writable and implements writable_backend_t.
-        *
-        * @param this          calling object
-        * @return                      TRUE if backend implements writable_backend_t.
-        */
-       bool (*is_writeable)(backend_t *this);
-       
-       /**
-        * @brief Destroy a backend.
-        *
-        * @param this          calling object
-        */
-       void (*destroy)(backend_t *this);
-};
-
-
-/**
- * Construction to create a backend.
- */
-typedef backend_t*(*backend_constructor_t)(void);
-
-#endif /* BACKEND_H_ */
-
diff --git a/src/charon/config/backends/local_backend.c b/src/charon/config/backends/local_backend.c
deleted file mode 100644 (file)
index e04c72a..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-/**
- * @file local_backend.c
- *
- * @brief Implementation of local_backend_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <string.h>
-
-#include "local_backend.h"
-
-#include <daemon.h>
-#include <utils/linked_list.h>
-#include <crypto/ca.h>
-
-
-typedef struct private_local_backend_t private_local_backend_t;
-
-/**
- * Private data of an local_backend_t object
- */
-struct private_local_backend_t {
-
-       /**
-        * Public part
-        */
-       local_backend_t public;
-       
-       /**
-        * list of configs
-        */
-       linked_list_t *cfgs;
-       
-       /**
-        * Mutex to exclusivly access list
-        */
-       pthread_mutex_t mutex;
-};
-
-/**
- * implements backen_t.get_ike_cfg.
- */
-static ike_cfg_t *get_ike_cfg(private_local_backend_t *this, 
-                                                         host_t *my_host, host_t *other_host)
-{
-       peer_cfg_t *peer;
-       ike_cfg_t *current, *found = NULL;
-       iterator_t *iterator;
-       host_t *my_candidate, *other_candidate;
-       enum {
-               MATCH_NONE  = 0x00,
-               MATCH_ANY   = 0x01,
-               MATCH_ME    = 0x04,
-               MATCH_OTHER = 0x08,
-       } prio, best = MATCH_ANY;
-       
-       DBG2(DBG_CFG, "looking for a config for %H...%H",
-                my_host, other_host);
-       
-       iterator = this->cfgs->create_iterator_locked(this->cfgs, &this->mutex);
-       while (iterator->iterate(iterator, (void**)&peer))
-       {
-               prio = MATCH_NONE;
-               current = peer->get_ike_cfg(peer);
-               my_candidate = current->get_my_host(current);
-               other_candidate = current->get_other_host(current);
-               
-               if (my_candidate->ip_equals(my_candidate, my_host))
-               {
-                       prio += MATCH_ME;
-               }
-               else if (my_candidate->is_anyaddr(my_candidate))
-               {
-                       prio += MATCH_ANY;
-               }
-               
-               if (other_candidate->ip_equals(other_candidate, other_host))
-               {
-                       prio += MATCH_OTHER;
-               }
-               else if (other_candidate->is_anyaddr(other_candidate))
-               {
-                       prio += MATCH_ANY;
-               }
-               
-               DBG2(DBG_CFG, "  candidate '%s': %H...%H, prio %d",
-                        peer->get_name(peer), my_candidate, other_candidate, prio);
-               
-               /* we require at least two MATCH_ANY */
-               if (prio > best)
-               {
-                       best = prio;
-                       found = current;
-               }
-       }
-       if (found)
-       {
-               found->get_ref(found);
-       }
-       iterator->destroy(iterator);
-       return found;
-}
-
-#define PRIO_NO_MATCH_FOUND            256
-
-/**
- * implements backend_t.get_peer.
- */                    
-static peer_cfg_t *get_peer_cfg(private_local_backend_t *this,
-                                                               identification_t *my_id, identification_t *other_id,
-                                                               ca_info_t *other_ca_info)
-{
-       peer_cfg_t *current, *found = NULL;
-       iterator_t *iterator;
-       identification_t *my_candidate, *other_candidate;
-       int best = PRIO_NO_MATCH_FOUND;
-       
-       DBG2(DBG_CFG, "looking for a config for %D...%D", my_id, other_id);
-       
-       iterator = this->cfgs->create_iterator_locked(this->cfgs, &this->mutex);
-       while (iterator->iterate(iterator, (void**)&current))
-       {
-               int wc1, wc2;
-
-               my_candidate = current->get_my_id(current);
-               other_candidate = current->get_other_id(current);
-
-               if (my_candidate->matches(my_candidate, my_id, &wc1)
-               &&      other_id->matches(other_id, other_candidate, &wc2))
-               {
-                       int prio = (wc1 + wc2) * (MAX_CA_PATH_LEN + 1);
-                       int pathlen = 0;
-                       identification_t *other_candidate_ca = current->get_other_ca(current);
-                       linked_list_t *groups = current->get_groups(current);
-
-                       /* is a group membership required? */
-                       if (groups->get_count(groups) > 0)
-                       {
-                               DBG1(DBG_CFG, "  group membership required");
-                       }
-
-                       /* are there any ca constraints? */
-                       if (other_candidate_ca->get_type(other_candidate_ca) != ID_ANY)
-                       {
-                               ca_info_t *ca_info = other_ca_info;
-
-                               for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
-                               {
-                                       if (ca_info == NULL)
-                                       {
-                                               prio = PRIO_NO_MATCH_FOUND;
-                                               break;
-                                       }
-                                       else
-                                       {
-                                               x509_t *cacert = ca_info->get_certificate(ca_info);
-                                               identification_t *other_ca = cacert->get_subject(cacert);
-
-                                               if (other_candidate_ca->equals(other_candidate_ca, other_ca))
-                                               {
-                                                       /* found a ca match */
-                                                       break;
-                                               }
-                                               if (cacert->is_self_signed(cacert))
-                                               {
-                                                       /* reached the root ca without a match */
-                                                       prio = PRIO_NO_MATCH_FOUND;
-                                                       break;
-                                               }
-                                               /* move a level upward in the trust path hierarchy */
-                                               ca_info = charon->credentials->get_issuer(charon->credentials, cacert); 
-                                       }
-                               }
-                               if (pathlen == MAX_CA_PATH_LEN)
-                               {
-                                       DBG1(DBG_CFG, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN);
-                                       prio = PRIO_NO_MATCH_FOUND;
-                               }
-                       }
-                       if (prio == PRIO_NO_MATCH_FOUND)
-                       {
-                               DBG2(DBG_CFG, "  candidate '%s': %D...%D, no ca match",
-                                       current->get_name(current), my_candidate, other_candidate);
-                       }
-                       else
-                       {
-                               prio += pathlen;
-                               DBG2(DBG_CFG, "  candidate '%s': %D...%D, prio %d",
-                                       current->get_name(current), my_candidate, other_candidate, prio);
-                       
-                               if (prio < best)
-                               {
-                                       found = current;
-                                       best = prio;
-                               }
-                       }
-               }
-       }
-       if (found)
-       {
-               DBG1(DBG_CFG, "found matching config \"%s\": %D...%D, prio %d",
-                               found->get_name(found),
-                               found->get_my_id(found),
-                               found->get_other_id(found),
-                               best);
-               found->get_ref(found);
-       }
-       iterator->destroy(iterator);
-       return found;
-}
-
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */                    
-static peer_cfg_t *get_peer_cfg_by_name(private_local_backend_t *this, char *name)
-{
-       iterator_t *i1, *i2;
-       peer_cfg_t *current, *found = NULL;
-       child_cfg_t *child;
-
-       i1 = this->cfgs->create_iterator(this->cfgs, TRUE);
-       while (i1->iterate(i1, (void**)&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 */
-        i2 = current->create_child_cfg_iterator(current);
-        while (i2->iterate(i2, (void**)&child))
-        {
-            if (streq(child->get_name(child), name))
-            {
-                found = current;
-                found->get_ref(found);
-                break;
-            }
-        }
-        i2->destroy(i2);
-        if (found)
-        {
-            break;
-        }
-       }
-       i1->destroy(i1);
-       return found;
-}
-
-/**
- * Implementation of backend_t.is_writable.
- */
-static bool is_writeable(private_local_backend_t *this)
-{
-    return TRUE;
-}
-
-/**
- * Implementation of writable_backend_t.create_iterator.
- */
-static iterator_t* create_iterator(private_local_backend_t *this)
-{
-       return this->cfgs->create_iterator_locked(this->cfgs, &this->mutex);
-}
-
-/**
- * Implementation of writable_backend_t.add_peer_cfg.
- */
-static void add_cfg(private_local_backend_t *this, peer_cfg_t *config)
-{
-    pthread_mutex_lock(&this->mutex);
-    this->cfgs->insert_last(this->cfgs, config);
-    pthread_mutex_unlock(&this->mutex);
-}
-
-/**
- * Implementation of backend_t.destroy.
- */
-static void destroy(private_local_backend_t *this)
-{
-    this->cfgs->destroy_offset(this->cfgs, offsetof(peer_cfg_t, destroy));
-    free(this);
-}
-
-/**
- * Described in header.
- */
-backend_t *backend_create(void)
-{
-       private_local_backend_t *this = malloc_thing(private_local_backend_t);
-       
-       this->public.backend.backend.get_ike_cfg = (ike_cfg_t* (*)(backend_t*, host_t*, host_t*))get_ike_cfg;
-       this->public.backend.backend.get_peer_cfg = (peer_cfg_t* (*)(backend_t*,identification_t*,identification_t*,ca_info_t*))get_peer_cfg;
-       this->public.backend.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
-    this->public.backend.backend.is_writeable = (bool(*) (backend_t*))is_writeable;
-    this->public.backend.backend.destroy = (void (*)(backend_t*))destroy;
-       this->public.backend.create_iterator = (iterator_t* (*)(writeable_backend_t*))create_iterator;
-    this->public.backend.add_cfg = (void (*)(writeable_backend_t*,peer_cfg_t*))add_cfg;
-    
-       /* private variables */
-       this->cfgs = linked_list_create();
-       pthread_mutex_init(&this->mutex, NULL);
-       
-       return &this->public.backend.backend;
-}
diff --git a/src/charon/config/backends/local_backend.h b/src/charon/config/backends/local_backend.h
deleted file mode 100644 (file)
index b33c644..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * @file local_backend.h
- *
- * @brief Interface of local_backend_t.
- *
- */
-
-/*
- * 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.
- */
-#ifndef LOCAL_BACKEND_H_
-#define LOCAL_BACKEND_H_
-
-typedef struct local_backend_t local_backend_t;
-
-#include <library.h>
-#include <config/backends/writeable_backend.h>
-
-/**
- * @brief An in-memory backend to store configurations.
- *
- * The local_backend_t stores the configuration in a simple list. It
- * implements both, backend_t and writeable_backend_t.
- *
- * @b Constructors:
- *  - local_backend_create()
- * 
- * @ingroup backends
- */
-struct local_backend_t {
-       
-       /**
-        * Implements writable_backend_t interface
-        */
-       writeable_backend_t backend;
-};
-
-/**
- * @brief Create a backend_t instance implemented as local backend.
- *
- * @return backend instance
- * 
- * @ingroup backends
- */
-backend_t *backend_create(void);
-
-#endif /* LOCAL_BACKEND_H_ */
-
diff --git a/src/charon/config/backends/sqlite_backend.c b/src/charon/config/backends/sqlite_backend.c
deleted file mode 100644 (file)
index e1c96c8..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-/**
- * @file sqlite_backend.c
- *
- * @brief Implementation of sqlite_backend_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <string.h>
-#include <sqlite3.h>
-
-#include "sqlite_backend.h"
-
-#include <daemon.h>
-
-
-typedef struct private_sqlite_backend_t private_sqlite_backend_t;
-
-/**
- * Private data of an sqlite_backend_t object
- */
-struct private_sqlite_backend_t {
-
-       /**
-        * Public part
-        */
-       sqlite_backend_t public;
-       
-       /**
-        * SQLite database handle
-        */
-       sqlite3 *db;
-};
-
-/**
- * implements backen_t.get_ike_cfg.
- */
-static ike_cfg_t *get_ike_cfg(private_sqlite_backend_t *this, 
-                                                         host_t *my_host, host_t *other_host)
-{
-       return NULL;
-}
-
-/**
- * add TS with child "id" to "child_cfg"
- */
-static void add_ts(private_sqlite_backend_t *this, child_cfg_t *child_cfg, int id)
-{
-       sqlite3_stmt *stmt;
-       
-       if (sqlite3_prepare_v2(this->db,
-               "SELECT type, protocol, start_addr, end_addr, start_port, end_port, kind "
-               "FROM traffic_selectors, child_config_traffic_selector "
-                       "ON traffic_selectors.oid = child_config_traffic_selector.traffic_selector "
-               "WHERE child_config_traffic_selector.child_cfg = ?;",
-               -1, &stmt, NULL) == SQLITE_OK &&
-               sqlite3_bind_int(stmt, 1, id) == SQLITE_OK)
-       {
-               while (sqlite3_step(stmt) == SQLITE_ROW)
-               {
-                       traffic_selector_t *ts;
-                       bool local = FALSE;
-                       enum {
-                               TS_LOCAL = 0,
-                               TS_REMOTE = 1,
-                               TS_LOCAL_DYNAMIC = 2,
-                               TS_REMOTE_DYNAMIC = 3,
-                       } kind;
-                       
-                       kind = sqlite3_column_int(stmt, 6);
-                       switch (kind)
-                       {
-                               case TS_LOCAL:
-                                       local = TRUE;
-                                       /* FALL */
-                               case TS_REMOTE:
-                                       ts = traffic_selector_create_from_string(
-                                               sqlite3_column_int(stmt, 1),                    /* protocol */
-                                               sqlite3_column_int(stmt, 0),                    /* type */
-                                               (char*)sqlite3_column_text(stmt, 2),    /* from addr */
-                                               sqlite3_column_int(stmt, 4),                    /* from port */
-                                               (char*)sqlite3_column_text(stmt, 3),    /* to addr */
-                                               sqlite3_column_int(stmt, 5));                   /* to port */
-                                       break;
-                               case TS_LOCAL_DYNAMIC:
-                                       local = TRUE;
-                                       /* FALL */
-                               case TS_REMOTE_DYNAMIC:
-                                       ts = traffic_selector_create_dynamic(
-                                               sqlite3_column_int(stmt, 1),                    /* protocol */
-                                               sqlite3_column_int(stmt, 0),                    /* type */
-                                               sqlite3_column_int(stmt, 4),                    /* from port */
-                                               sqlite3_column_int(stmt, 5));                   /* to port */
-                                       break;
-                               default:
-                                       continue;
-                       }
-                       if (ts)
-                       {
-                               child_cfg->add_traffic_selector(child_cfg, local, ts);
-                       }
-               }
-       }
-       sqlite3_finalize(stmt);
-}
-
-/**
- * add childrens belonging to config with "id" to "peer_cfg"
- */
-static void add_children(private_sqlite_backend_t *this, peer_cfg_t *peer_cfg, int id)
-{
-       sqlite3_stmt *stmt;
-       child_cfg_t *child_cfg;
-       
-       if (sqlite3_prepare_v2(this->db,
-               "SELECT child_configs.oid, name, updown, hostaccess, mode, "
-                          "lifetime, rekeytime, jitter "
-               "FROM child_configs, peer_config_child_config "
-                       "ON child_configs.oid = peer_config_child_config.child_cfg "
-               "WHERE peer_config_child_config.peer_cfg = ?;",
-               -1, &stmt, NULL) == SQLITE_OK &&
-               sqlite3_bind_int(stmt, 1, id) == SQLITE_OK)
-       {
-               while (sqlite3_step(stmt) == SQLITE_ROW)
-               {
-                       child_cfg = child_cfg_create(
-                                       (char*)sqlite3_column_text(stmt, 1),    /* name */
-                                       sqlite3_column_int(stmt, 5),                    /* lifetime */
-                                       sqlite3_column_int(stmt, 6),                    /* rekeytime */
-                                       sqlite3_column_int(stmt, 7),                    /* jitter */
-                                       (char*)sqlite3_column_text(stmt, 2),    /* updown */
-                                       sqlite3_column_int(stmt, 3),                    /* hostaccess */
-                                       sqlite3_column_int(stmt, 4));                   /* mode */
-                       add_ts(this, child_cfg, sqlite3_column_int(stmt, 0));
-                       child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
-                       peer_cfg->add_child_cfg(peer_cfg, child_cfg);
-               }
-       }
-       sqlite3_finalize(stmt);
-}
-
-/**
- * processing function for get_peer_cfg and get_peer_cfg_by_name
- */
-static peer_cfg_t *process_peer_cfg_row(private_sqlite_backend_t *this,
-                                                                               sqlite3_stmt *stmt)
-{
-       host_t *local_host, *remote_host, *local_vip = NULL, *remote_vip = NULL;
-       identification_t *local_id, *remote_id;
-       peer_cfg_t *peer_cfg;
-       ike_cfg_t *ike_cfg;
-
-       local_host = host_create_from_string((char*)sqlite3_column_text(stmt, 17), IKEV2_UDP_PORT);
-       remote_host = host_create_from_string((char*)sqlite3_column_text(stmt, 18), IKEV2_UDP_PORT);
-       if (sqlite3_column_text(stmt, 15))
-       {
-               local_vip = host_create_from_string((char*)sqlite3_column_text(stmt, 15), 0);
-       }
-       if (sqlite3_column_text(stmt, 16))
-       {
-               remote_vip = host_create_from_string((char*)sqlite3_column_text(stmt, 16), 0);
-       }
-       local_id = identification_create_from_string((char*)sqlite3_column_text(stmt, 2));
-       remote_id = identification_create_from_string((char*)sqlite3_column_text(stmt, 3));
-       if (local_host && remote_host && local_id && remote_id)
-       {
-               ike_cfg = ike_cfg_create(sqlite3_column_int(stmt, 19),  FALSE,
-                                                                local_host, remote_host);              
-               ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
-               peer_cfg = peer_cfg_create(
-                       (char*)sqlite3_column_text(stmt, 1),            /* name */
-                       2, ike_cfg,     local_id, remote_id, NULL, NULL, linked_list_create(),
-                       sqlite3_column_int(stmt, 4),                            /* cert_policy */
-                       sqlite3_column_int(stmt, 5),                            /* auth_method */
-                       sqlite3_column_int(stmt, 6), 0                          /* eap_type, vendor */
-                       sqlite3_column_int(stmt, 7),                            /* keyingtries */
-                       sqlite3_column_int(stmt, 8),                            /* rekey_time */
-                       sqlite3_column_int(stmt, 9),                            /* reauth_time */
-                       sqlite3_column_int(stmt, 10),                           /* jitter_time */
-                       sqlite3_column_int(stmt, 11),                           /* over_time */
-                       sqlite3_column_int(stmt, 14),                           /* mobike */
-                       sqlite3_column_int(stmt, 12),                           /* dpd_delay */
-                       sqlite3_column_int(stmt, 13),                           /* dpd_action */
-                       local_vip, remote_vip, FALSE, NULL, NULL);
-               add_children(this, peer_cfg, sqlite3_column_int(stmt, 0));
-               return peer_cfg;
-       }
-       
-       DESTROY_IF(local_host);
-       DESTROY_IF(remote_host);
-       DESTROY_IF(local_id);
-       DESTROY_IF(remote_id);
-       DESTROY_IF(local_vip);
-       DESTROY_IF(remote_vip);
-       return NULL;
-}
-
-/**
- * implements backend_t.get_peer_cfg.
- */                    
-static peer_cfg_t *get_peer_cfg(private_sqlite_backend_t *this,
-                                                               identification_t *my_id, identification_t *other_id,
-                                                               ca_info_t *other_ca_info)
-{
-       sqlite3_stmt *stmt;
-       char local[256], remote[256];
-       peer_cfg_t *peer_cfg = NULL;
-
-       snprintf(local, sizeof(local), "%D",  my_id);
-       snprintf(remote, sizeof(remote), "%D", other_id);
-       
-       if (sqlite3_prepare_v2(this->db,
-                       "SELECT peer_configs.oid, name, local_id, remote_id, cert_policy, "
-                                  "auth_method, eap_type, keyingtries, "
-                                  "rekey_time, reauth_time, jitter_time, over_time, "
-                                  "dpd_delay, dpd_action, mobike, local_vip, remote_vip, "
-                                  "local, remote, certreq "
-                       "FROM peer_configs, ike_configs "
-                               "ON peer_configs.ike_cfg = ike_configs.oid "
-                       "WHERE local_id = ? and remote_id = ?;", -1, &stmt, NULL) == SQLITE_OK &&
-               sqlite3_bind_text(stmt, 1, local, -1, SQLITE_STATIC) == SQLITE_OK &&
-               sqlite3_bind_text(stmt, 2, remote, -1, SQLITE_STATIC) == SQLITE_OK &&
-               sqlite3_step(stmt) == SQLITE_ROW)
-       {
-               peer_cfg = process_peer_cfg_row(this, stmt);
-       }
-       sqlite3_finalize(stmt);
-       return peer_cfg;
-}
-
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */                    
-static peer_cfg_t *get_peer_cfg_by_name(private_sqlite_backend_t *this, char *name)
-{
-       sqlite3_stmt *stmt;
-       peer_cfg_t *peer_cfg = NULL;
-       
-       if (sqlite3_prepare_v2(this->db,
-                       "SELECT peer_configs.oid, name, local_id, remote_id, cert_policy, "
-                                  "auth_method, eap_type, keyingtries, lifetime, rekeytime, jitter, "
-                                  "dpd_delay, dpd_action, reauth, mobike, local_vip, remote_vip, "
-                                  "local, remote, certreq "
-                       "FROM peer_configs, ike_configs "
-                               "ON peer_configs.ike_cfg = ike_configs.oid "
-                       "WHERE name = ? ;", -1, &stmt, NULL) == SQLITE_OK &&
-               sqlite3_bind_text(stmt, 1, name, -1, SQLITE_STATIC) == SQLITE_OK &&
-               sqlite3_step(stmt) == SQLITE_ROW)
-       {
-               peer_cfg = process_peer_cfg_row(this, stmt);
-       }
-       sqlite3_finalize(stmt);
-       return peer_cfg;
-}
-
-/**
- * Implementation of backend_t.is_writable.
- */
-static bool is_writeable(private_sqlite_backend_t *this)
-{
-    return FALSE;
-}
-
-/**
- * Implementation of backend_t.destroy.
- */
-static void destroy(private_sqlite_backend_t *this)
-{
-       sqlite3_close(this->db);
-    free(this);
-}
-
-/**
- * Described in header.
- */
-backend_t *backend_create(void)
-{
-       private_sqlite_backend_t *this = malloc_thing(private_sqlite_backend_t);
-
-       this->public.backend.get_ike_cfg = (ike_cfg_t* (*)(backend_t*, host_t*, host_t*))get_ike_cfg;
-       this->public.backend.get_peer_cfg = (peer_cfg_t* (*)(backend_t*,identification_t*,identification_t*,ca_info_t*))get_peer_cfg;
-       this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
-       this->public.backend.is_writeable = (bool(*) (backend_t*))is_writeable;
-       this->public.backend.destroy = (void (*)(backend_t*))destroy;
-       
-       if (sqlite3_open(IPSEC_DIR "/manager.db", &this->db) != SQLITE_OK)
-       {
-               DBG1(DBG_CFG, "opening SQLite database '" IPSEC_DIR "/manager.db' failed.");
-               destroy(this);
-               return NULL;
-       }
-       
-       return &this->public.backend;
-}
-
diff --git a/src/charon/config/backends/writeable_backend.h b/src/charon/config/backends/writeable_backend.h
deleted file mode 100644 (file)
index ea62f62..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file writeable_backend.h
- *
- * @brief Interface of writeable_backend_t.
- *
- */
-
-/*
- * 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.
- */
-#ifndef WRITEABLE_BACKEND_H_
-#define WRITEABLE_BACKEND_H_
-
-typedef struct writeable_backend_t writeable_backend_t;
-
-#include <library.h>
-#include <config/backends/backend.h>
-
-/**
- * @brief A writeable backend extends backend_t by modification functions.
- *
- * @b Constructors:
- *  - writeable_backend_create()
- * 
- * @ingroup backends
- */
-struct writeable_backend_t {
-       
-       /**
-        * Implements backend_t interface
-        */
-       backend_t backend;
-       
-       /**
-        * @brief Add a peer_config to the backend.
-        *
-        * @param this          calling object
-        * @param config        peer_config to add to the backend
-        */
-       void (*add_cfg)(writeable_backend_t *this, peer_cfg_t *config);
-       
-       /**
-        * @brief Create an iterator over all peer configs.
-        *
-        * @param this          calling object
-        * @return                      iterator over peer configs
-        */
-       iterator_t* (*create_iterator)(writeable_backend_t *this);
-};
-
-#endif /* WRITEABLE_BACKEND_H_ */
-
index 5827b4f61498c121626fee7f4846aa879e02b4da..b4bc95707abb59467b47122ce41823a9f5b4ebc4 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_cfg.c
- * 
- * @brief Implementation of child_cfg_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 "child_cfg.h"
 
 #include <daemon.h>
index e1a6553b47f6847a2b42fe35e6b725ad708cefcf..c7401d623c4f61513add949e88b3139d0bbeab26 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_cfg.h
- * 
- * @brief Interface of child_cfg_t.
- *  
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 child_cfg child_cfg
+ * @{ @ingroup config
  */
 
 #ifndef CHILD_CFG_H_
@@ -32,11 +32,9 @@ typedef struct child_cfg_t child_cfg_t;
 #include <config/traffic_selector.h>
 
 /**
- * @brief Mode of an CHILD_SA.
+ * Mode of an CHILD_SA.
  *
  * These are equal to those defined in XFRM, so don't change.
- *
- * @ingroup config
  */
 enum mode_t {
        /** transport mode, no inner address */
@@ -53,7 +51,7 @@ enum mode_t {
 extern enum_name_t *mode_names;
 
 /**
- * @brief A child_cfg_t defines the config template for a CHILD_SA.
+ * A child_cfg_t defines the config template for a CHILD_SA.
  *
  * After creation, proposals and traffic selectors may be added to the config.
  * A child_cfg object is referenced multiple times, and is not thread save.
@@ -62,51 +60,42 @@ extern enum_name_t *mode_names;
  * A reference counter handles the number of references hold to this config.
  *
  * @see peer_cfg_t to get an overview over the configurations.
- * 
- * @b Constructors:
- *   - child_cfg_create()
- *
- * @ingroup config
  */
 struct child_cfg_t {
        
        /**
-        * @brief Get the name of the child_cfg.
+        * Get the name of the child_cfg.
         * 
-        * @param this                  calling object
         * @return                              child_cfg's name
         */
        char *(*get_name) (child_cfg_t *this);
        
        /**
-        * @brief Add a proposal to the list. 
+        * Add a proposal to the list. 
         * 
         * The proposals are stored by priority, first added
         * is the most prefered.
         * After add, proposal is owned by child_cfg.
         * 
-        * @param this                  calling object
         * @param proposal              proposal to add
         */
        void (*add_proposal) (child_cfg_t *this, proposal_t *proposal);
        
        /**
-        * @brief Get the list of proposals for the CHILD_SA.
+        * Get the list of proposals for the CHILD_SA.
         *
         * Resulting list and all of its proposals must be freed after use.
         * 
-        * @param this                  calling object
         * @param strip_dh              TRUE strip out diffie hellman groups
         * @return                              list of proposals
         */
        linked_list_t* (*get_proposals)(child_cfg_t *this, bool strip_dh);
        
        /**
-        * @brief Select a proposal from a supplied list.
+        * Select a proposal from a supplied list.
         *
         * Returned propsal is newly created and must be destroyed after usage.
         * 
-        * @param this                  calling object
         * @param proposals             list from from wich proposals are selected
         * @param strip_dh              TRUE strip out diffie hellman groups
         * @return                              selected proposal, or NULL if nothing matches
@@ -115,12 +104,11 @@ struct child_cfg_t {
                                                                   bool strip_dh);
        
        /**
-        * @brief Add a traffic selector to the config.
+        * Add a traffic selector to the config.
         * 
         * Use the "local" parameter to add it for the local or the remote side.
         * After add, traffic selector is owned by child_cfg.
         * 
-        * @param this                  calling object
         * @param local                 TRUE for local side, FALSE for remote
         * @param ts                    traffic_selector to add
         */
@@ -128,7 +116,7 @@ struct child_cfg_t {
                                                                 traffic_selector_t *ts);
        
        /**
-        * @brief Get a list of traffic selectors to use for the CHILD_SA.
+        * Get a list of traffic selectors to use for the CHILD_SA.
         * 
         * The config contains two set of traffic selectors, one for the local
         * side, one for the remote side.
@@ -139,7 +127,6 @@ struct child_cfg_t {
         * the "host" parameter to narrow such traffic selectors to that address.
         * Resulted list and its traffic selectors must be destroyed after use.
         * 
-        * @param this                  calling object
         * @param local                 TRUE for TS on local side, FALSE for remote
         * @param supplied              list with TS to select from, or NULL
         * @param host                  address to use for narrowing "dynamic" TS', or NULL
@@ -150,23 +137,21 @@ struct child_cfg_t {
                                                                                        host_t *host);
 
        /**
-        * @brief Get the updown script to run for the CHILD_SA.
+        * Get the updown script to run for the CHILD_SA.
         * 
-        * @param this                  calling object
         * @return                              path to updown script
         */
        char* (*get_updown)(child_cfg_t *this);
        
        /**
-        * @brief Should we allow access to the local host (gateway)?
+        * Should we allow access to the local host (gateway)?
         * 
-        * @param this                  calling object
         * @return                              value of hostaccess flag
         */
        bool (*get_hostaccess) (child_cfg_t *this);
 
        /**
-        * @brief Get the lifetime of a CHILD_SA.
+        * Get the lifetime of a CHILD_SA.
         *
         * If "rekey" is set to TRUE, a lifetime is returned before the first
         * rekeying should be started. If it is FALSE, the actual lifetime is
@@ -174,57 +159,50 @@ struct child_cfg_t {
         * The rekey time automatically contains a jitter to avoid simlutaneous
         * rekeying.
         * 
-        * @param this                  child_cfg 
         * @param rekey                 TRUE to get rekey time
         * @return                              lifetime in seconds
         */
        u_int32_t (*get_lifetime) (child_cfg_t *this, bool rekey);
        
        /**
-        * @brief Get the mode to use for the CHILD_SA.
+        * Get the mode to use for the CHILD_SA.
         *
         * The mode is either tunnel, transport or BEET. The peer must agree
         * on the method, fallback is tunnel mode.
         * 
-        * @param this                  child_cfg
         * @return                              lifetime in seconds
         */
        mode_t (*get_mode) (child_cfg_t *this);
        
        /**
-        * @brief Get the DH group to use for CHILD_SA setup.
+        * Get the DH group to use for CHILD_SA setup.
         * 
-        * @param this          calling object
-        * @return                      dh group to use
+        * @return                              dh group to use
         */
        diffie_hellman_group_t (*get_dh_group)(child_cfg_t *this);
        
        /**
-        * @brief Get a new reference.
+        * Get a new reference.
         *
         * Get a new reference to this child_cfg by increasing
         * it's internal reference counter.
         * Do not call get_ref or any other function until you
         * already have a reference. Otherwise the object may get
         * destroyed while calling get_ref(),
-        * 
-        * @param this                          calling object
         */
        void (*get_ref) (child_cfg_t *this);
        
        /**
-        * @brief Destroys the child_cfg object.
+        * Destroys the child_cfg object.
         *
         * Decrements the internal reference counter and
         * destroys the child_cfg when it reaches zero.
-        * 
-        * @param this                          calling object
         */
        void (*destroy) (child_cfg_t *this);
 };
 
 /**
- * @brief Create a configuration template for CHILD_SA setup.
+ * Create a configuration template for CHILD_SA setup.
  * 
  * The "name" string gets cloned.
  * Lifetimes are in seconds. To prevent to peers to start rekeying at the
@@ -241,11 +219,9 @@ struct child_cfg_t {
  * @param hostaccess           TRUE to allow access to the local host
  * @param mode                         mode to propose for CHILD_SA, transport, tunnel or BEET
  * @return                                     child_cfg_t object
- * 
- * @ingroup config
  */
 child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
                                                          u_int32_t rekeytime, u_int32_t jitter,
                                                          char *updown, bool hostaccess, mode_t mode);
 
-#endif /* CHILD_CFG_H_ */
+#endif /* CHILD_CFG_H_ @} */
diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c
deleted file mode 100644 (file)
index 4067261..0000000
+++ /dev/null
@@ -1,1620 +0,0 @@
-/**
- * @file local_credential_store.c
- * 
- * @brief Implementation of local_credential_store_t.
- *  
- */
-
-/*
- * Copyright (C) 2006 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.
- *
- * RCSID $Id$
- */
-
-#include <sys/stat.h>
-#include <dirent.h>
-#include <string.h>
-#include <pthread.h>
-#include <errno.h>
-
-#include <library.h>
-#include <utils/lexparser.h>
-#include <utils/linked_list.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <crypto/certinfo.h>
-#include <crypto/x509.h>
-#include <crypto/ca.h>
-#include <crypto/ac.h>
-#include <crypto/crl.h>
-#include <asn1/ttodata.h>
-
-#include "local_credential_store.h"
-
-#define PATH_BUF                       256
-
-typedef struct shared_key_t shared_key_t;
-
-/**
- * Private date of a shared_key_t object
- */
-struct shared_key_t {
-
-       /**
-        * shared secret
-        */
-       chunk_t secret;
-
-       /**
-        * list of peer IDs
-        */
-       linked_list_t *peers;
-};
-
-
-/**
- * Implementation of shared_key_t.destroy.
- */
-static void shared_key_destroy(shared_key_t *this)
-{
-       this->peers->destroy_offset(this->peers, offsetof(identification_t, destroy));
-       chunk_free_randomized(&this->secret);
-       free(this);
-}
-
-/**
- * @brief Creates a shared_key_t object.
- * 
- * @param shared_key           shared key value
- * @return                                     shared_key_t object
- * 
- * @ingroup config
- */
-static shared_key_t *shared_key_create(chunk_t secret)
-{
-       shared_key_t *this = malloc_thing(shared_key_t);
-
-       /* private data */
-       this->secret = secret;
-       this->peers = linked_list_create();
-
-       return (this);
-}
-
-/* ------------------------------------------------------------------------ *
- * the ca_info_t object as a central control element
-
-+--------------------------------------------------------+
-| local_credential_store_t                               |
-+--------------------------------------------------------+
-  |                              |
-+---------------------------+  +-------------------------+
-| linked_list_t *auth_certs |  | linked_list_t *ca_infos |
-+---------------------------+  +-------------------------+
-  |                              |
-  |                 +------------------------- +
-  |                 | ca_info_t                |
-  |                 +--------------------------+
-+---------------+   | char *name               |
-| x509_t        |<--| x509_t *cacert           |
-+---------------+   | linked_list_t *attrcerts |   +----------------------+
-| chunk_t keyid |   | linked_list_t *certinfos |-->| certinfo_t           |
-+---------------+   | linked_list_t *ocspuris  |   +----------------------+
-  |                 | crl_t *crl               |   | chunk_t serialNumber |
-  |                 | linked_list_t *crluris   |   | cert_status_t status |
-+---------------+   | pthread_mutex_t mutex    |   | time_t thisUpdate    |
-| x509_t        |   +--------------------------+   | time_t nextUpdate    |
-+---------------+                |                 | bool once            |
-| chunk_t keyid |                |                 +----------------------+
-+---------------+   +------------------------- +     |
-  |                 | ca_info_t                |   +----------------------+
-  |                 +--------------------------+   | certinfo_t           |
-+---------------+   | char *name               |   +----------------------+
-| x509_t        |<--| x509_t *cacert           |   | chunk_t serialNumber |
-+---------------+   | linked_list_t *attrcerts |   | cert_status_t status |
-| chunk_t keyid |   | linked_list_t *certinfos |   | time_t thisUpdate    |
-+---------------+   | linked_list_t *ocspuris  |   | time_t nextUpdate    |
-  |                 | crl_t *crl               |   | bool once            |
-  |                 | linked_list_t *crluris   |   +----------------------+
-  |                 | pthread_mutex_t mutex;   |     |
-  |                 +--------------------------+
-  |                              |
-
- * ------------------------------------------------------------------------ */
-
-typedef struct private_local_credential_store_t private_local_credential_store_t;
-
-/**
- * Private data of an local_credential_store_t object
- */
-struct private_local_credential_store_t {
-
-       /**
-        * Public part
-        */
-       local_credential_store_t public;
-       
-       /**
-        * list of shared keys
-        */
-       linked_list_t *shared_keys;
-       
-       /**
-        * list of EAP keys
-        */
-       linked_list_t *eap_keys;
-       
-       /**
-        * list of key_entry_t's with private keys
-        */
-       linked_list_t *private_keys;
-       
-       /**
-        * mutex controls access to the linked lists of secret keys
-        */
-       pthread_mutex_t keys_mutex;
-
-       /**
-        * list of X.509 certificates with public keys
-        */
-       linked_list_t *certs;
-
-       /**
-        * list of X.509 authority certificates with public keys
-        */
-       linked_list_t *auth_certs;
-
-       /**
-        * list of X.509 CA information records
-        */
-       linked_list_t *ca_infos;
-
-       /**
-        * list of X.509 attribute certificates
-        */
-       linked_list_t *acerts;
-
-       /**
-        * mutex controls access to the linked list of attribute certificates
-        */
-       pthread_mutex_t acerts_mutex;
-};
-
-
-/**
- * Get a key from a list with shared_key_t's
- */    
-static status_t get_key(linked_list_t *keys,
-                                                          identification_t *my_id,
-                                                          identification_t *other_id, chunk_t *secret)
-{
-       typedef enum {
-               PRIO_UNDEFINED=         0x00,
-               PRIO_ANY_MATCH=         0x01,
-               PRIO_MY_MATCH=          0x02,
-               PRIO_OTHER_MATCH=       0x04,
-       } prio_t;
-
-       prio_t best_prio = PRIO_UNDEFINED;
-       chunk_t found = chunk_empty;
-       shared_key_t *shared_key;
-       iterator_t *iterator;
-
-       iterator = keys->create_iterator(keys, TRUE);
-
-       while (iterator->iterate(iterator, (void**)&shared_key))
-       {
-               iterator_t *peer_iterator;
-               identification_t *peer_id;
-               prio_t prio = PRIO_UNDEFINED;
-
-               peer_iterator = shared_key->peers->create_iterator(shared_key->peers, TRUE);
-
-               if (peer_iterator->get_count(peer_iterator) == 0)
-               {
-                       /* this is a wildcard shared key */
-                       prio = PRIO_ANY_MATCH;
-               }
-               else
-               {
-                       while (peer_iterator->iterate(peer_iterator, (void**)&peer_id))
-                       {
-                               if (my_id->equals(my_id, peer_id))
-                               {
-                                       prio |= PRIO_MY_MATCH; 
-                               }
-                               if (other_id->equals(other_id, peer_id))
-                               {
-                                       prio |= PRIO_OTHER_MATCH; 
-                               }
-                       }
-               }
-               peer_iterator->destroy(peer_iterator);
-
-               if (prio > best_prio)
-               {
-                       best_prio = prio;
-                       found = shared_key->secret;
-               }
-       }
-       iterator->destroy(iterator);
-
-       if (best_prio == PRIO_UNDEFINED)
-       {
-               return NOT_FOUND;
-       }
-       else
-       {
-               *secret = chunk_clone(found);
-               return SUCCESS;
-       }
-}
-
-/**
- * Implementation of local_credential_store_t.get_shared_key.
- */    
-static status_t get_shared_key(private_local_credential_store_t *this,
-                                                          identification_t *my_id,
-                                                          identification_t *other_id, chunk_t *secret)
-{
-       status_t status;
-
-       pthread_mutex_lock(&(this->keys_mutex));
-       status = get_key(this->shared_keys, my_id, other_id, secret);
-       pthread_mutex_unlock(&(this->keys_mutex));
-       return status;
-}
-
-/**
- * Implementation of local_credential_store_t.get_eap_key.
- */    
-static status_t get_eap_key(private_local_credential_store_t *this,
-                                                       identification_t *my_id,
-                                                       identification_t *other_id, chunk_t *secret)
-{
-       status_t status;
-
-       pthread_mutex_lock(&(this->keys_mutex));
-       status = get_key(this->eap_keys, my_id, other_id, secret);
-       pthread_mutex_unlock(&(this->keys_mutex));
-       return status;
-}
-
-/**
- * Implementation of credential_store_t.get_certificate.
- */
-static x509_t* get_certificate(private_local_credential_store_t *this,
-                                                          identification_t *id)
-{
-       x509_t *found = NULL;
-       x509_t *current_cert;
-
-       iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
-
-       while (iterator->iterate(iterator, (void**)&current_cert))
-       {
-               if (id->equals(id, current_cert->get_subject(current_cert)) ||
-                       current_cert->equals_subjectAltName(current_cert, id))
-               {
-                       found = current_cert;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       return found;
-}
-
-/**
- * Implementation of local_credential_store_t.get_rsa_public_key.
- */
-static rsa_public_key_t *get_rsa_public_key(private_local_credential_store_t *this,
-                                                                                       identification_t *id)
-{
-       x509_t *cert = get_certificate(this, id);
-
-       return (cert == NULL)? NULL:cert->get_public_key(cert);
-}
-
-/**
- * Implementation of credential_store_t.get_issuer.
- */
-static ca_info_t* get_issuer(private_local_credential_store_t *this, x509_t *cert)
-{
-       ca_info_t *found = cert->get_ca_info(cert);
-
-       if (found == NULL)
-       {
-               iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
-               ca_info_t *ca_info;
-
-               while (iterator->iterate(iterator, (void**)&ca_info))
-               {
-                       if (ca_info->is_cert_issuer(ca_info, cert))
-                       {
-                               found = ca_info;
-                               cert->set_ca_info(cert, found);
-                               break;
-                       }
-               }
-               iterator->destroy(iterator);
-       }
-       return found;
-}
-
-/**
- * Implementation of local_credential_store_t.has_rsa_private_key.
- */
-static bool has_rsa_private_key(private_local_credential_store_t *this, rsa_public_key_t *pubkey)
-{
-       bool found = FALSE;
-       rsa_private_key_t *current;
-       iterator_t *iterator;
-
-       pthread_mutex_lock(&(this->keys_mutex));
-       iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
-
-       while (iterator->iterate(iterator, (void**)&current))
-       {
-               if (current->belongs_to(current, pubkey))
-               {
-                       found = TRUE;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       pthread_mutex_unlock(&(this->keys_mutex));
-       return found;
-}
-
-/**
- * Implementation of credential_store_t.get_auth_certificate.
- */
-static x509_t* get_auth_certificate(private_local_credential_store_t *this,
-                                                                       u_int auth_flags,
-                                                                       identification_t *id)
-{
-       x509_t *found = NULL;
-       x509_t *current_cert;
-
-       iterator_t *iterator = this->auth_certs->create_iterator(this->auth_certs, TRUE);
-
-       while (iterator->iterate(iterator, (void**)&current_cert))
-       {
-               if (current_cert->has_authority_flag(current_cert, auth_flags)
-               &&  id->equals(id, current_cert->get_subject(current_cert)))
-               {
-                       found = current_cert;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-
-       return found;
-}
-
-/**
- * Implementation of credential_store_t.get_ca_certificate_by_keyid.
- */
-static x509_t* get_ca_certificate_by_keyid(private_local_credential_store_t *this,
-                                                                                  chunk_t keyid)
-{
-       x509_t *found = NULL;
-       x509_t *current_cert;
-
-       iterator_t *iterator = this->auth_certs->create_iterator(this->auth_certs, TRUE);
-
-       while (iterator->iterate(iterator, (void**)&current_cert))
-       {
-               rsa_public_key_t *pubkey = current_cert->get_public_key(current_cert);
-
-               if (current_cert->has_authority_flag(current_cert, AUTH_CA)
-               &&  chunk_equals(keyid, pubkey->get_keyid(pubkey)))
-               {
-                       found = current_cert;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-
-       return found;
-}
-
-/**
- * Find an exact copy of a certificate in a linked list
- */
-static x509_t* find_certificate(linked_list_t *certs, x509_t *cert)
-{
-       x509_t *found_cert = NULL, *current_cert;
-
-       iterator_t *iterator = certs->create_iterator(certs, TRUE);
-
-       while (iterator->iterate(iterator, (void**)&current_cert))
-       {
-               if (cert->equals(cert, current_cert))
-               {
-                       found_cert = current_cert;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-
-       return found_cert;
-}
-
-/**
- * Adds crl and ocsp uris to the corresponding issuer info record
- */
-static void add_uris(ca_info_t *issuer, x509_t *cert)
-{
-       iterator_t *iterator;
-       identification_t *uri;
-
-       /* add any crl distribution points to the issuer ca info record */
-       iterator = cert->create_crluri_iterator(cert);
-       
-       while (iterator->iterate(iterator, (void**)&uri))
-       {
-               if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
-               {
-                       issuer->add_crluri(issuer, uri->get_encoding(uri));
-               }
-       }
-       iterator->destroy(iterator);
-
-       /* add any ocsp access points to the issuer ca info record */
-       iterator = cert->create_ocspuri_iterator(cert);
-       
-       while (iterator->iterate(iterator, (void**)&uri))
-       {
-               if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
-               {
-                       issuer->add_ocspuri(issuer, uri->get_encoding(uri));
-               }
-       }
-       iterator->destroy(iterator);
-}
-
-/**
- * Implementation of credential_store_t.is_trusted
- */
-static bool is_trusted(private_local_credential_store_t *this, const char *label, x509_t *cert)
-{
-       int pathlen;
-       time_t until = UNDEFINED_TIME;
-       x509_t *cert_to_be_trusted = cert;
-
-       DBG1(DBG_CFG, "establishing trust in %s certificate:", label);
-
-       for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
-       {
-               err_t ugh = NULL;
-               ca_info_t *issuer;
-               x509_t *issuer_cert;
-               rsa_public_key_t *issuer_public_key;
-               bool valid_signature;
-
-               DBG1(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
-               DBG1(DBG_CFG, "issuer:  '%D'", cert->get_issuer(cert));
-
-               ugh = cert->is_valid(cert, &until);
-               if (ugh != NULL)
-               {
-                       DBG1(DBG_CFG, "certificate %s", ugh);
-                       return FALSE;
-               }
-               DBG2(DBG_CFG, "certificate is valid");
-       
-               issuer = get_issuer(this, cert);
-               if (issuer == NULL)
-               {
-                       DBG1(DBG_CFG, "issuer not found");
-                       return FALSE;
-               }
-               DBG2(DBG_CFG, "issuer found");
-
-               issuer_cert = issuer->get_certificate(issuer);
-               issuer_public_key = issuer_cert->get_public_key(issuer_cert);
-               valid_signature = cert->verify(cert, issuer_public_key);
-
-               if (!valid_signature)
-               {
-                       DBG1(DBG_CFG, "certificate signature is invalid");
-                       return FALSE;
-               }
-               DBG2(DBG_CFG, "certificate signature is valid");
-
-               /* check if cert is a self-signed root ca */
-               if (pathlen > 0 && cert->is_self_signed(cert))
-               {
-                       DBG1(DBG_CFG, "reached self-signed root ca");
-                       cert_to_be_trusted->set_until(cert_to_be_trusted, until);
-                       cert_to_be_trusted->set_status(cert_to_be_trusted, CERT_GOOD);
-                       return TRUE;
-               }
-               else
-               {
-                       DBG1(DBG_CFG, "going up one step in the certificate trust chain (%d)",
-                                                  pathlen + 1);
-                       cert = issuer_cert;
-               }
-       }
-       DBG1(DBG_CFG, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN);
-       return FALSE;
-}
-
-/**
- * Implementation of credential_store_t.verify.
- */
-static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *found)
-{
-       int pathlen;
-       time_t until = UNDEFINED_TIME;
-
-       x509_t *end_cert = cert;
-       x509_t *cert_copy = find_certificate(this->certs, end_cert);
-       
-       DBG1(DBG_CFG, "verifying end entity certificate up to trust anchor:");
-
-       *found = (cert_copy != NULL);
-       if (*found)
-       {
-               DBG2(DBG_CFG,
-                        "end entitity certificate is already in credential store");
-       }
-
-       for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
-       {
-               bool valid_signature;
-               err_t ugh = NULL;
-               ca_info_t *issuer;
-               x509_t *issuer_cert;
-               rsa_public_key_t *issuer_public_key;
-               chunk_t keyid = cert->get_keyid(cert);
-
-               DBG1(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
-               DBG1(DBG_CFG, "issuer:  '%D'", cert->get_issuer(cert));
-               DBG1(DBG_CFG, "keyid:    %#B", &keyid);
-
-               ugh = cert->is_valid(cert, &until);
-               if (ugh != NULL)
-               {
-                       DBG1(DBG_CFG, "certificate %s", ugh);
-                       return FALSE;
-               }
-               DBG2(DBG_CFG, "certificate is valid");
-
-               issuer = get_issuer(this, cert);
-               if (issuer == NULL)
-               {
-                       DBG1(DBG_CFG, "issuer not found");
-                       return FALSE;
-               }
-               DBG2(DBG_CFG, "issuer found");
-
-               issuer_cert = issuer->get_certificate(issuer);
-               issuer_public_key = issuer_cert->get_public_key(issuer_cert);
-               valid_signature = cert->verify(cert, issuer_public_key);
-
-               if (!valid_signature)
-               {
-                       DBG1(DBG_CFG, "certificate signature is invalid");
-                       return FALSE;
-               }
-               DBG2(DBG_CFG, "certificate signature is valid");
-
-               /* check if cert is a self-signed root ca */
-               if (pathlen > 0 && cert->is_self_signed(cert))
-               {
-                       DBG1(DBG_CFG, "reached self-signed root ca");
-
-                       /* set the definite status and trust interval of the end entity certificate */
-                       end_cert->set_until(end_cert, until);
-                       if (cert_copy)
-                       {
-                               cert_copy->set_status(cert_copy, end_cert->get_status(end_cert));
-                               cert_copy->set_until(cert_copy, until);
-                       }
-                       return TRUE;
-               }
-               else
-               {
-                       bool strict;
-                       time_t nextUpdate;
-                       cert_status_t status;
-                       certinfo_t *certinfo = certinfo_create(cert->get_serialNumber(cert));
-
-                       if (pathlen == 0)
-                       {
-                               /* add any crl and ocsp uris contained in the certificate under test */
-                               add_uris(issuer, cert);
-                       }
-
-                       strict = issuer->is_strict(issuer);
-                       DBG1(DBG_CFG, "issuer %s a strict crl policy",
-                                strict ? "enforces":"does not enforce");
-
-                       /* first check certificate revocation using ocsp */
-                       status = issuer->verify_by_ocsp(issuer, certinfo, &this->public.credential_store);
-
-                       /* if ocsp service is not available then fall back to crl */
-                       if ((status == CERT_UNDEFINED) || (status == CERT_UNKNOWN && strict))
-                       {
-
-                               certinfo->set_status(certinfo, CERT_UNKNOWN);
-                               status = issuer->verify_by_crl(issuer, certinfo, CRL_DIR);
-                       }
-                       
-                       nextUpdate = certinfo->get_nextUpdate(certinfo);
-                       cert->set_status(cert, status);
-
-                       switch (status)
-                       {
-                               case CERT_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)
-                                       {
-                                               cert->set_until(cert, nextUpdate);
-                                               until = (nextUpdate < until)? nextUpdate : until;
-                                       }
-
-                                       /* if status information is stale */
-                                       if (strict && nextUpdate < time(NULL))
-                                       {
-                                               DBG2(DBG_CFG, "certificate is good but status is stale");
-                                               certinfo->destroy(certinfo);
-                                               return FALSE;
-                                       }
-                                       DBG1(DBG_CFG, "certificate is good");
-                                       break;
-                               case CERT_REVOKED:
-                                       {
-                                               time_t revocationTime = certinfo->get_revocationTime(certinfo);
-                                               DBG1(DBG_CFG,
-                                                        "certificate was revoked on %T, reason: %N",
-                                                        &revocationTime, crl_reason_names,
-                                                        certinfo->get_revocationReason(certinfo));
-
-                                               /* set revocationTime */
-                                               cert->set_until(cert, revocationTime);
-
-                                               /* update status of end certificate in the credential store */
-                                               if (cert_copy)
-                                               {
-                                                       if (pathlen > 0)
-                                                       {
-                                                               cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
-                                                       }
-                                                       else
-                                                       {
-                                                               cert_copy->set_status(cert_copy, CERT_REVOKED);
-                                                               cert_copy->set_until(cert_copy,
-                                                                               certinfo->get_revocationTime(certinfo));
-                                                       }
-                                               }
-                                               certinfo->destroy(certinfo);
-                                               return FALSE;
-                                       }
-                               case CERT_UNKNOWN:
-                               case CERT_UNDEFINED:
-                               default:
-                                       DBG1(DBG_CFG, "certificate status unknown");
-                                       if (strict)
-                                       {
-                                               /* update status of end certificate in the credential store */
-                                               if (cert_copy)
-                                               {
-                                                       cert_copy->set_status(cert_copy, CERT_UNTRUSTED);
-                                               }
-                                               certinfo->destroy(certinfo);
-                                               return FALSE;
-                                       }
-                                       break;
-                       }
-                       certinfo->destroy(certinfo);
-               }
-               DBG1(DBG_CFG, "going up one step in the certificate trust chain (%d)",
-                                          pathlen + 1);
-               cert = issuer_cert;
-       }
-       DBG1(DBG_CFG, "maximum ca path length of %d levels reached", MAX_CA_PATH_LEN);
-       return FALSE;
-}
-
-/**
- * Implementation of local_credential_store_t.rsa_signature.
- */
-static status_t rsa_signature(private_local_credential_store_t *this,
-                                                         rsa_public_key_t *pubkey,
-                                                         hash_algorithm_t hash_algorithm,
-                                                         chunk_t data, chunk_t *signature)
-{
-       rsa_private_key_t *current, *key = NULL;
-       iterator_t *iterator;
-       status_t status;
-       chunk_t keyid = pubkey->get_keyid(pubkey);
-
-       DBG2(DBG_IKE, "looking for RSA private key with keyid %#B...", &keyid);
-       pthread_mutex_lock(&(this->keys_mutex));
-
-       iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
-       while (iterator->iterate(iterator, (void**)&current))
-       {
-               if (current->belongs_to(current, pubkey))
-               {
-                       key = current;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-
-       if (key)
-       {
-               DBG2(DBG_IKE, "  matching RSA private key found");
-               status = key->build_emsa_pkcs1_signature(key, hash_algorithm, data, signature);
-       }
-       else
-       {
-               DBG1(DBG_IKE, "no RSA private key found with keyid %#B", &keyid);
-               status = NOT_FOUND;
-       }
-       pthread_mutex_unlock(&(this->keys_mutex));
-       return status;
-}
-
-/**
- * Implementation of local_credential_store_t.verify_signature.
- */
-static status_t verify_signature(private_local_credential_store_t *this,
-                                                                chunk_t hash, chunk_t signature,
-                                                                identification_t *id, ca_info_t **issuer_p)
-{
-       iterator_t *iterator = this->certs->create_iterator(this->certs, TRUE);
-       status_t sig_status;
-       x509_t *cert;
-
-       /* default return values in case of failure */
-       sig_status = NOT_FOUND;
-       *issuer_p = NULL;
-
-       while (iterator->iterate(iterator, (void**)&cert))
-       {
-               if (id->equals(id, cert->get_subject(cert))
-               ||      cert->equals_subjectAltName(cert, id))
-               {
-                       rsa_public_key_t *public_key = cert->get_public_key(cert);
-                       cert_status_t cert_status = cert->get_status(cert);
-                       
-                       DBG2(DBG_CFG, "found candidate peer certificate");
-
-                       if (cert_status == CERT_UNDEFINED || cert->get_until(cert) < time(NULL))
-                       {
-                               bool found;
-
-                               if (!verify(this, cert, &found))
-                               {
-                                       sig_status = VERIFY_ERROR;
-                                       DBG1(DBG_CFG, "candidate peer certificate was not successfully verified");
-                                       continue;
-                               }
-                               *issuer_p = get_issuer(this, cert);
-                       }
-                       else
-                       {
-                               ca_info_t *issuer = get_issuer(this, cert);
-                               chunk_t keyid = public_key->get_keyid(public_key);
-
-                               DBG2(DBG_CFG, "subject: '%D'", cert->get_subject(cert));
-                               DBG2(DBG_CFG, "issuer:  '%D'", cert->get_issuer(cert));
-                               DBG2(DBG_CFG, "keyid:    %#B", &keyid);
-
-                               if (issuer == NULL)
-                               {
-                                       DBG1(DBG_CFG, "candidate peer certificate has no retrievable issuer");
-                                       sig_status = NOT_FOUND;
-                                       continue;
-                               }
-                               if (cert_status == CERT_REVOKED || cert_status == CERT_UNTRUSTED
-                               || ((issuer)->is_strict(issuer) && cert_status != CERT_GOOD))
-                               {
-                                       DBG1(DBG_CFG, "candidate peer certificate has an inacceptable status: %N", cert_status_names, cert_status);
-                                       sig_status = VERIFY_ERROR;
-                                       continue;
-                               }
-                               *issuer_p = issuer;
-                       }
-                       sig_status = public_key->verify_emsa_pkcs1_signature(public_key, HASH_UNKNOWN, hash, signature);
-                       if (sig_status == SUCCESS)
-                       {
-                               DBG2(DBG_CFG, "candidate peer certificate has a matching RSA public key");
-                               break;
-                       }
-                       else
-                       {
-                               DBG1(DBG_CFG, "candidate peer certificate has a non-matching RSA public key");
-                               *issuer_p = NULL;
-                       }
-               }
-       }
-       iterator->destroy(iterator);
-       if (sig_status == NOT_FOUND)
-       {
-               DBG1(DBG_CFG, "no candidate peer certificate found");
-       }
-       return sig_status;
-}
-
-/**
- * Add a unique certificate to a linked list
- */
-static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
-{
-       x509_t *found_cert = find_certificate(certs, cert);
-
-       if (found_cert)
-       {
-               /* add the authority flags */
-               found_cert->add_authority_flags(found_cert, cert->get_authority_flags(cert));
-
-               cert->destroy(cert);
-               return found_cert;
-       }
-       else
-       {
-               certs->insert_last(certs, (void*)cert);
-               return cert;
-       }
-}
-
-/**
- * Add a unique ca info record to a linked list
- */
-static ca_info_t* add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_info)
-{
-       ca_info_t *current_ca_info;
-       ca_info_t *found_ca_info = NULL;
-
-       iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
-
-       while (iterator->iterate(iterator, (void**)&current_ca_info))
-       {
-               if (current_ca_info->equals(current_ca_info, ca_info))
-               {
-                       found_ca_info = current_ca_info;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-
-       if (found_ca_info)
-       {
-               current_ca_info->add_info(current_ca_info, ca_info);
-               ca_info->destroy(ca_info);
-               ca_info = found_ca_info;
-       }
-       else
-       {
-               this->ca_infos->insert_last(this->ca_infos, (void*)ca_info);
-       }
-       return ca_info;
-}
-
-/**
- * Release ca info record of a given name
- */
-static status_t release_ca_info(private_local_credential_store_t *this, const char *name)
-{
-       status_t status = NOT_FOUND;
-       ca_info_t *ca_info;
-
-       iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
-
-       while (iterator->iterate(iterator, (void**)&ca_info))
-       {
-               if (ca_info->equals_name_release_info(ca_info, name))
-               {
-                       status = SUCCESS;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       
-       return status;
-}
-
-/**
- * Implements local_credential_store_t.add_end_certificate
- */
-static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert)
-{
-       x509_t *ret_cert = add_certificate(this->certs, cert);
-
-       /* add crl and ocsp uris the first time the certificate is added */
-       if (ret_cert == cert)
-       {
-               ca_info_t *issuer = get_issuer(this, cert);
-
-               if (issuer)
-               {
-                       add_uris(issuer, cert);
-               }
-       }
-       return ret_cert;
-}
-
-/**
- * Implements local_credential_store_t.add_auth_certificate
- */
-static x509_t* add_auth_certificate(private_local_credential_store_t *this, x509_t *cert, u_int auth_flags)
-{
-       cert->add_authority_flags(cert, auth_flags);
-       return add_certificate(this->auth_certs, cert);
-}
-
-/**
- * Implements local_credential_store_t.create_cert_iterator
- */
-static iterator_t* create_cert_iterator(private_local_credential_store_t *this)
-{
-       return this->certs->create_iterator(this->certs, TRUE);
-}
-
-/**
- * Implements local_credential_store_t.create_cacert_iterator
- */
-static iterator_t* create_auth_cert_iterator(private_local_credential_store_t *this)
-{
-       return this->auth_certs->create_iterator(this->auth_certs, TRUE);
-}
-
-/**
- * Implements local_credential_store_t.create_cainfo_iterator
- */
-static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this)
-{
-       return this->ca_infos->create_iterator(this->ca_infos, TRUE);
-}
-
-/**
- * Implements local_credential_store_t.create_acert_iterator
- */
-static iterator_t* create_acert_iterator(private_local_credential_store_t *this)
-{
-       return this->acerts->create_iterator_locked(this->acerts, &this->acerts_mutex);
-}
-
-/**
- * Implements local_credential_store_t.load_auth_certificates
- */
-static void load_auth_certificates(private_local_credential_store_t *this,
-                                                                  u_int auth_flag,
-                                                                  const char* label,
-                                                                  const char* path)
-{
-       struct dirent* entry;
-       struct stat stb;
-       DIR* dir;
-       
-       DBG1(DBG_CFG, "loading %s certificates from '%s'", label, path);
-
-       dir = opendir(path);
-       if (dir == NULL)
-       {
-               DBG1(DBG_CFG, "error opening %s certs directory '%s'", label, path);
-               return;
-       }
-
-       while ((entry = readdir(dir)) != NULL)
-       {
-               char file[PATH_BUF];
-
-               snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
-               
-               if (stat(file, &stb) == -1)
-               {
-                       continue;
-               }
-               /* try to parse all regular files */
-               if (stb.st_mode & S_IFREG)
-               {
-                       x509_t *cert = x509_create_from_file(file, label);
-
-                       if (cert)
-                       {
-                               err_t ugh = cert->is_valid(cert, NULL);
-
-                               if (ugh != NULL)
-                               {
-                                       DBG1(DBG_CFG, "warning: %s certificate %s", label, ugh);
-                               }
-
-                               if (auth_flag == AUTH_CA && !cert->is_ca(cert))
-                               {
-                                       DBG1(DBG_CFG, "  CA basic constraints flag not set, cert discarded");
-                                       cert->destroy(cert);
-                               }
-                               else
-                               {
-                                       x509_t *ret_cert;
-
-                                       cert->add_authority_flags(cert, auth_flag);
-
-                                       ret_cert = add_certificate(this->auth_certs, cert);
-
-                                       if (auth_flag == AUTH_CA && ret_cert == cert)
-                                       {
-                                               ca_info_t *ca_info = ca_info_create(NULL, cert);
-
-                                               add_ca_info(this, ca_info);
-                                       }
-                               }
-                       }
-               }
-       }
-       closedir(dir);
-}
-
-/**
- * Implements local_credential_store_t.load_ca_certificates
- */
-static void load_ca_certificates(private_local_credential_store_t *this)
-{
-       load_auth_certificates(this, AUTH_CA, "ca", CA_CERTIFICATE_DIR);
-
-       /* add any crl and ocsp uris found in the ca certificates to the
-     * corresponding issuer info record. We can do this only after all
-     * ca certificates have been loaded and the ca hierarchy is known.
-     */
-       {
-               iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
-               ca_info_t *ca_info;
-
-               while (iterator->iterate(iterator, (void **)&ca_info))
-               {
-                       if (ca_info->is_ca(ca_info))
-                       {
-                               x509_t *cacert = ca_info->get_certificate(ca_info);
-                               ca_info_t *issuer = get_issuer(this, cacert);
-
-                               if (issuer)
-                               {
-                                       add_uris(issuer, cacert);
-                               }
-                       }
-               }
-               iterator->destroy(iterator);
-       }
-}
-
-/**
- * Implements local_credential_store_t.load_aa_certificates
- */
-static void load_aa_certificates(private_local_credential_store_t *this)
-{
-       load_auth_certificates(this, AUTH_AA, "aa", AA_CERTIFICATE_DIR);
-}
-
-/**
- * Add a unique attribute certificate to a linked list
- */
-static void add_attr_certificate(private_local_credential_store_t *this, x509ac_t *cert)
-{
-       iterator_t *iterator;
-       x509ac_t *current_cert;
-       bool found = FALSE;
-
-       pthread_mutex_lock(&(this->acerts_mutex));
-       iterator = this->acerts->create_iterator(this->acerts, TRUE);
-
-       while (iterator->iterate(iterator, (void **)&current_cert))
-       {
-               if (cert->equals_holder(cert, current_cert))
-               {
-                       if (cert->is_newer(cert, current_cert))
-                       {
-                               iterator->replace(iterator, NULL, (void *)cert);
-                               current_cert->destroy(current_cert);
-                               DBG1(DBG_CFG, "  this attr cert is newer - existing attr cert replaced");
-                       }
-                       else
-                       {
-                               cert->destroy(cert);
-                               DBG1(DBG_CFG, "  this attr cert is not newer - existing attr cert retained");
-                       }
-                       found = TRUE;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-
-       if (!found)
-       {
-               this->acerts->insert_last(this->acerts, (void *)cert);
-       }
-       pthread_mutex_unlock(&(this->acerts_mutex));
-}
-
-/**
- * Implements local_credential_store_t.load_attr_certificates
- */
-static void load_attr_certificates(private_local_credential_store_t *this)
-{
-       struct dirent* entry;
-       struct stat stb;
-       DIR* dir;
-
-       const char *path = ATTR_CERTIFICATE_DIR;
-       
-       DBG1(DBG_CFG, "loading attribute certificates from '%s'", path);
-
-       dir = opendir(ATTR_CERTIFICATE_DIR);
-       if (dir == NULL)
-       {
-               DBG1(DBG_CFG, "error opening attribute certs directory '%s'", path);
-               return;
-       }
-
-       while ((entry = readdir(dir)) != NULL)
-       {
-               char file[PATH_BUF];
-
-               snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
-               
-               if (stat(file, &stb) == -1)
-               {
-                       continue;
-               }
-               /* try to parse all regular files */
-               if (stb.st_mode & S_IFREG)
-               {
-                       x509ac_t *cert = x509ac_create_from_file(file);
-
-                       if (cert)
-                       {
-                               err_t ugh = cert->is_valid(cert, NULL);
-
-                               if (ugh != NULL)
-                               {
-                                       DBG1(DBG_CFG, "warning: attribute certificate %s", ugh);
-                               }
-                               add_attr_certificate(this, cert);
-                       }
-               }
-       }
-       closedir(dir);
-
-
-}
-
-/**
- * Implements local_credential_store_t.load_ocsp_certificates
- */
-static void load_ocsp_certificates(private_local_credential_store_t *this)
-{
-       load_auth_certificates(this, AUTH_OCSP, "ocsp", OCSP_CERTIFICATE_DIR);
-}
-
-/**
- * Add the latest crl to the issuing ca
- */
-static void add_crl(private_local_credential_store_t *this, crl_t *crl, const char *path)
-{
-       iterator_t *iterator = this->ca_infos->create_iterator(this->ca_infos, TRUE);
-       ca_info_t *ca_info;
-       bool found = FALSE;
-
-       while (iterator->iterate(iterator, (void**)&ca_info))
-       {
-               if (ca_info->is_ca(ca_info) && ca_info->is_crl_issuer(ca_info, crl))
-               {
-                       char buffer[BUF_LEN];
-                       chunk_t uri = { buffer, 7 + strlen(path) };
-
-                       ca_info->add_crl(ca_info, crl);
-                       if (uri.len < BUF_LEN)
-                       {
-                               snprintf(buffer, BUF_LEN, "file://%s", path);
-                               ca_info->add_crluri(ca_info, uri);
-                       }
-                       found = TRUE;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       
-       if (!found)
-       {
-               crl->destroy(crl);
-               DBG2(DBG_CFG, "  no issuing ca found for this crl - discarded");
-       }
-}
-
-/**
- * Implements local_credential_store_t.load_crls
- */
-static void load_crls(private_local_credential_store_t *this)
-{
-       struct dirent* entry;
-       struct stat stb;
-       DIR* dir;
-       crl_t *crl;
-       
-       DBG1(DBG_CFG, "loading crls from '%s'", CRL_DIR);
-
-       dir = opendir(CRL_DIR);
-       if (dir == NULL)
-       {
-               DBG1(DBG_CFG, "error opening crl directory '%s'", CRL_DIR);
-               return;
-       }
-
-       while ((entry = readdir(dir)) != NULL)
-       {
-               char file[PATH_BUF];
-
-               snprintf(file, sizeof(file), "%s/%s", CRL_DIR, entry->d_name);
-               
-               if (stat(file, &stb) == -1)
-               {
-                       continue;
-               }
-               /* try to parse all regular files */
-               if (stb.st_mode & S_IFREG)
-               {
-                       crl = crl_create_from_file(file);
-                       if (crl)
-                       {
-                               DBG1(DBG_CFG, "  crl is %s", crl->is_valid(crl)? "valid":"stale");
-                               add_crl(this, crl, file);
-                       }
-               }
-       }
-       closedir(dir);
-}
-
-/**
- * Convert a string of characters into a binary secret
- * A string between single or double quotes is treated as ASCII characters
- * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
- */
-static err_t extract_secret(chunk_t *secret, chunk_t *line)
-{
-       chunk_t raw_secret;
-       char delimiter = ' ';
-       bool quotes = FALSE;
-
-       if (!eat_whitespace(line))
-       {
-               return "missing secret";
-       }
-
-       if (*line->ptr == '\'' || *line->ptr == '"')
-       {
-               quotes = TRUE;
-               delimiter = *line->ptr;
-               line->ptr++;  line->len--;
-       }
-
-       if (!extract_token(&raw_secret, delimiter, line))
-       {
-               if (delimiter == ' ')
-               {
-                       raw_secret = *line;
-               }
-               else
-               {
-                       return "missing second delimiter";
-               }
-       }
-
-       if (quotes)
-       {       
-               /* treat as an ASCII string */
-               *secret = chunk_clone(raw_secret);
-       }
-       else
-       {
-               size_t len;
-               err_t ugh;
-
-               /* secret converted to binary form doesn't use more space than the raw_secret */
-               *secret = chunk_alloc(raw_secret.len);
-
-               /* convert from HEX or Base64 to binary */
-               ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len);
-
-           if (ugh != NULL)
-               {
-                       chunk_free_randomized(secret);
-                       return ugh;
-               }
-               secret->len = len;
-       }
-       return NULL;
-}
-
-/**
- * Implements local_credential_store_t.load_secrets
- */
-static void load_secrets(private_local_credential_store_t *this, bool reload)
-{
-       FILE *fd = fopen(SECRETS_FILE, "r");
-
-       if (fd)
-       {
-               size_t bytes;
-               int line_nr = 0;
-       chunk_t chunk, src, line;
-
-               DBG1(DBG_CFG, "%sloading secrets from \"%s\"",
-                       reload? "re":"", SECRETS_FILE);
-
-               fseek(fd, 0, SEEK_END);
-               chunk.len = ftell(fd);
-               rewind(fd);
-               chunk.ptr = malloc(chunk.len);
-               bytes = fread(chunk.ptr, 1, chunk.len, fd);
-               fclose(fd);
-               src = chunk;
-
-               pthread_mutex_lock(&(this->keys_mutex));
-               if (reload)
-               {
-                       DBG1(DBG_CFG, "  forgetting old secrets");
-                       this->private_keys->destroy_offset(this->private_keys,
-                                        offsetof(rsa_private_key_t, destroy));
-                       this->private_keys = linked_list_create();
-
-                       this->shared_keys->destroy_function(this->shared_keys,
-                                        (void*)shared_key_destroy);
-                       this->shared_keys = linked_list_create();
-
-                       this->eap_keys->destroy_function(this->eap_keys,
-                                        (void*)shared_key_destroy);
-                       this->eap_keys = linked_list_create();
-               }
-
-               while (fetchline(&src, &line))
-               {
-                       chunk_t ids, token;
-                       bool is_eap = FALSE;
-
-                       line_nr++;
-
-                       if (!eat_whitespace(&line))
-                       {
-                               continue;
-                       }
-                       if (!extract_last_token(&ids, ':', &line))
-                       {
-                               DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr);
-                               goto error;
-                       }
-                       /* NULL terminate the ids string by replacing the : separator */
-                       *(ids.ptr + ids.len) = '\0';
-
-                       if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
-                       {
-                               DBG1(DBG_CFG, "line %d: missing token", line_nr);
-                               goto error;
-                       }
-                       if (match("RSA", &token))
-                       {
-                               char path[PATH_BUF];
-                               chunk_t filename;
-                               chunk_t secret = chunk_empty;
-                               chunk_t *passphrase = NULL;
-
-                               rsa_private_key_t *key;
-
-                               err_t ugh = extract_value(&filename, &line);
-
-                               if (ugh != NULL)
-                               {
-                                       DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
-                                       goto error;
-                               }
-                               if (filename.len == 0)
-                               {
-                                       DBG1(DBG_CFG, "line %d: empty filename", line_nr);
-                                       goto error;
-                               }
-                               if (*filename.ptr == '/')
-                               {
-                                       /* absolute path name */
-                                       snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
-                               }
-                               else
-                               {
-                                       /* relative path name */
-                                       snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR, 
-                                                        filename.len, filename.ptr);
-                               }
-
-                               /* check for optional passphrase */
-                               if (eat_whitespace(&line))
-                               {
-                                       ugh = extract_secret(&secret, &line);
-                                       if (ugh != NULL)
-                                       {
-                                               DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
-                                               goto error;
-                                       }
-                                       if (secret.len > 0)
-                                               passphrase = &secret;
-                               }
-                               key = rsa_private_key_create_from_file(path, passphrase);
-                               if (key)
-                               {
-                                       this->private_keys->insert_last(this->private_keys, (void*)key);
-                               }
-                               chunk_free_randomized(&secret);
-                       }
-                       else if ( match("PSK", &token) ||
-                                       ((match("EAP", &token) || match("XAUTH", &token)) && (is_eap = TRUE)))
-                       {
-                               shared_key_t *shared_key;
-                               chunk_t secret = chunk_empty;
-
-                               err_t ugh = extract_secret(&secret, &line);
-                               if (ugh != NULL)
-                               {
-                                       DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
-                                       goto error;
-                               }
-                               
-                               DBG1(DBG_CFG, "  loading %s key for %s", 
-                                        is_eap ? "EAP" : "shared", 
-                                        ids.len > 0 ? (char*)ids.ptr : "%any");
-
-                               DBG4(DBG_CFG, "  secret:", secret);
-
-                               shared_key = shared_key_create(secret);
-                               if (is_eap)
-                               {
-                                       this->eap_keys->insert_last(this->eap_keys, (void*)shared_key);
-                               }
-                               else
-                               {
-                                       this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
-                               }
-                               while (ids.len > 0)
-                               {
-                                       chunk_t id;
-                                       identification_t *peer_id;
-
-                                       ugh = extract_value(&id, &ids);
-                                       if (ugh != NULL)
-                                       {
-                                               DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
-                                               goto error;
-                                       }
-                                       if (id.len == 0)
-                                       {
-                                               continue;
-                                       }
-
-                                       /* 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;
-                                       }
-                                       shared_key->peers->insert_last(shared_key->peers, (void*)peer_id);
-                               }
-                       }
-                       else if (match("PIN", &token))
-                       {
-
-                       }
-                       else
-                       {
-                               DBG1(DBG_CFG, "line %d: token must be either "
-                                        "RSA, PSK, EAP, or PIN", line_nr, token.len);
-                               goto error;
-                       }
-               }
-error:
-               chunk_free_randomized(&chunk);
-               pthread_mutex_unlock(&(this->keys_mutex));
-       }
-       else
-       {
-               DBG1(DBG_CFG, "could not open file '%s': %s", SECRETS_FILE,
-                        strerror(errno));
-       }
-}
-
-/**
- * Implementation of local_credential_store_t.destroy.
- */
-static void destroy(private_local_credential_store_t *this)
-{
-       this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
-       this->auth_certs->destroy_offset(this->auth_certs, offsetof(x509_t, destroy));
-       this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
-
-       pthread_mutex_lock(&(this->acerts_mutex));
-       this->acerts->destroy_offset(this->acerts, offsetof(x509ac_t, destroy));
-       pthread_mutex_unlock(&(this->acerts_mutex));
-
-       pthread_mutex_lock(&(this->keys_mutex));
-       this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
-       this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
-       this->eap_keys->destroy_function(this->eap_keys, (void*)shared_key_destroy);
-       pthread_mutex_unlock(&(this->keys_mutex));
-
-       free(this);
-}
-
-/**
- * Described in header.
- */
-local_credential_store_t * local_credential_store_create(void)
-{
-       private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
-
-       /* public functions */
-       this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key;
-       this->public.credential_store.get_eap_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_eap_key;
-       this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
-       this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
-       this->public.credential_store.get_certificate = (x509_t* (*) (credential_store_t*,identification_t*))get_certificate;
-       this->public.credential_store.get_auth_certificate = (x509_t* (*) (credential_store_t*,u_int,identification_t*))get_auth_certificate;
-       this->public.credential_store.get_ca_certificate_by_keyid = (x509_t* (*) (credential_store_t*,chunk_t))get_ca_certificate_by_keyid;
-       this->public.credential_store.get_issuer = (ca_info_t* (*) (credential_store_t*,x509_t*))get_issuer;
-       this->public.credential_store.is_trusted = (bool (*) (credential_store_t*,const char*,x509_t*))is_trusted;
-       this->public.credential_store.rsa_signature = (status_t (*) (credential_store_t*,rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t*))rsa_signature;
-       this->public.credential_store.verify_signature = (status_t (*) (credential_store_t*,chunk_t,chunk_t,identification_t*,ca_info_t**))verify_signature;
-       this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
-       this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
-       this->public.credential_store.add_auth_certificate = (x509_t* (*) (credential_store_t*,x509_t*,u_int))add_auth_certificate;
-       this->public.credential_store.add_ca_info = (ca_info_t* (*) (credential_store_t*,ca_info_t*))add_ca_info;
-       this->public.credential_store.release_ca_info = (status_t (*) (credential_store_t*,const char*))release_ca_info;
-       this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
-       this->public.credential_store.create_auth_cert_iterator = (iterator_t* (*) (credential_store_t*))create_auth_cert_iterator;
-       this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator;
-       this->public.credential_store.create_acert_iterator = (iterator_t* (*) (credential_store_t*))create_acert_iterator;
-       this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates;
-       this->public.credential_store.load_aa_certificates = (void (*) (credential_store_t*))load_aa_certificates;
-       this->public.credential_store.load_attr_certificates = (void (*) (credential_store_t*))load_attr_certificates;
-       this->public.credential_store.load_ocsp_certificates = (void (*) (credential_store_t*))load_ocsp_certificates;
-       this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls;
-       this->public.credential_store.load_secrets = (void (*) (credential_store_t*,bool))load_secrets;
-       this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy;
-
-       /* initialize the mutexes */
-       pthread_mutex_init(&(this->keys_mutex), NULL);
-       pthread_mutex_init(&(this->acerts_mutex), NULL);
-
-       /* private variables */
-       this->shared_keys = linked_list_create();
-       this->eap_keys = linked_list_create();
-       this->private_keys = linked_list_create();
-       this->certs = linked_list_create();
-       this->auth_certs = linked_list_create();
-       this->ca_infos = linked_list_create();
-       this->acerts = linked_list_create();
-
-       return (&this->public);
-}
diff --git a/src/charon/config/credentials/local_credential_store.h b/src/charon/config/credentials/local_credential_store.h
deleted file mode 100644 (file)
index 87a1266..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file local_credential_store.h
- *
- * @brief Interface of local_credential_store_t.
- *
- */
-
-/*
- * Copyright (C) 2006 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.
- */
-#ifndef LOCAL_CREDENTIAL_H_
-#define LOCAL_CREDENTIAL_H_
-
-typedef struct local_credential_store_t local_credential_store_t;
-
-#include <library.h>
-#include <credential_store.h>
-#include <daemon.h>
-
-
-/**
- * @brief A credential_store_t implementation using simple credentail lists.
- *
- * The local_credential_store_t class implements the credential_store_t interface
- * as simple as possible. The credentials are stored in lists, and are loaded from
- * files on the disk.
- * Shared secret are not handled yet, so get_shared_secret always returns NOT_FOUND.
- *
- * @b Constructors:
- *  - local_credential_store_create(bool strict)
- * 
- * @ingroup config
- */
-struct local_credential_store_t {
-       
-       /**
-        * Implements credential_store_t interface
-        */
-       credential_store_t credential_store;
-};
-
-/**
- * @brief Creates a local_credential_store_t instance.
- *
- * @return                             credential store instance.
- *
- * @ingroup config
- */
-local_credential_store_t *local_credential_store_create(void);
-
-#endif /* LOCAL_CREDENTIAL_H_ */
index abb300aab435442da610ada8a9250fc725d49e72..5c994ae3c83754dcc1cbc9ca0104e0b50b3b73b1 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_cfg.c
- *
- * @brief Implementation of ike_cfg_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "ike_cfg.h"
index 5165d12a640e3c7d7b899f2abcd364cd1673cdb9..d28da9b8d235b1e56697a912e5bb0b0cd078b95c 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_cfg.h
- *
- * @brief Interface of ike_cfg_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 ike_cfg ike_cfg
+ * @{ @ingroup config
  */
 
 #ifndef IKE_CFG_H_
@@ -34,115 +34,98 @@ typedef struct ike_cfg_t ike_cfg_t;
 #include <crypto/diffie_hellman.h>
 
 /**
- * @brief An ike_cfg_t defines the rules to set up an IKE_SA.
+ * An ike_cfg_t defines the rules to set up an IKE_SA.
  *
  * @see peer_cfg_t to get an overview over the configurations.
- *
- * @b Constructors:
- *  - ike_cfg_create()
- *
- * @ingroup config
  */
 struct ike_cfg_t {
        
        /**
-        * @brief Get own address.
+        * Get own address.
         * 
-        * @param this  calling object
         * @return              host information as host_t object
         */
        host_t* (*get_my_host) (ike_cfg_t *this);
 
        /**
-        * @brief Get peers address.
+        * Get peers address.
         * 
-        * @param this  calling object
         * @return              host information as host_t object
         */
        host_t* (*get_other_host) (ike_cfg_t *this);
        
        /**
-        * @brief Adds a proposal to the list.
+        * Adds a proposal to the list.
         * 
         * The first added proposal has the highest priority, the last
         * added the lowest.
         * 
-        * @param this          calling object
         * @param proposal      proposal to add
         */
        void (*add_proposal) (ike_cfg_t *this, proposal_t *proposal);
        
        /**
-        * @brief Returns a list of all supported proposals.
+        * Returns a list of all supported proposals.
         * 
         * Returned list and its proposals must be destroyed after use.
         * 
-        * @param this          calling object
         * @return                      list containing all the proposals
         */
        linked_list_t* (*get_proposals) (ike_cfg_t *this);
        
        /**
-        * @brief Select a proposed from suggested proposals.
+        * Select a proposed from suggested proposals.
         * 
         * Returned proposal must be destroyed after use.
         * 
-        * @param this          calling object
         * @param proposals     list of proposals to select from
         * @return                      selected proposal, or NULL if none matches.
         */
        proposal_t *(*select_proposal) (ike_cfg_t *this, linked_list_t *proposals);
        
        /**
-        * @brief Should we send a certificate request in IKE_SA_INIT?
+        * Should we send a certificate request in IKE_SA_INIT?
         *
-        * @param this          calling object
         * @return                      certificate request sending policy
         */
        bool (*send_certreq) (ike_cfg_t *this);
        
        /**
-        * @brief Enforce UDP encapsulation by faking NATD notifies?
+        * Enforce UDP encapsulation by faking NATD notifies?
         * 
-        * @param this          calling object
         * @return                      TRUE to enfoce UDP encapsulation
         */
        bool (*force_encap) (ike_cfg_t *this);
        
        /**
-        * @brief Get the DH group to use for IKE_SA setup.
+        * Get the DH group to use for IKE_SA setup.
         * 
-        * @param this          calling object
         * @return                      dh group to use for initialization
         */
        diffie_hellman_group_t (*get_dh_group)(ike_cfg_t *this);
        
        /**
-        * @brief Get a new reference to this ike_cfg.
+        * Get a new reference to this ike_cfg.
         *
         * Get a new reference to this ike_cfg by increasing
         * it's internal reference counter.
         * Do not call get_ref or any other function until you
         * already have a reference. Otherwise the object may get
         * destroyed while calling get_ref(),
-        *
-        * @param this          calling object
         */
        void (*get_ref) (ike_cfg_t *this);
        
        /**
-        * @brief Destroys a ike_cfg_t object.
+        * Destroys a ike_cfg_t object.
         * 
         * Decrements the internal reference counter and
         * destroys the ike_cfg when it reaches zero.
-        * 
-        * @param this          calling object
         */
        void (*destroy) (ike_cfg_t *this);
 };
 
 /**
- * @brief Creates a ike_cfg_t object.
+ * Creates a ike_cfg_t object.
  *
  * Supplied hosts become owned by ike_cfg, the name gets cloned.
  *
@@ -152,10 +135,8 @@ struct ike_cfg_t {
  * @param my_host              host_t representing local address
  * @param other_host   host_t representing remote address
  * @return                             ike_cfg_t object.
- * 
- * @ingroup config
  */
 ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap, 
                                                  host_t *my_host, host_t *other_host);
 
-#endif /* IKE_CFG_H_ */
+#endif /* IKE_CFG_H_ @} */
index 0b5d391c4c0be52e2cea508a415f2916f392ccc9..1547f53aac555ff9f15ff09af0b7866ed4b98dc9 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file peer_cfg.c
- * 
- * @brief Implementation of peer_cfg_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
@@ -20,6 +13,8 @@
  * WITHOUT ANY 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>
@@ -29,7 +24,6 @@
 
 #include <utils/linked_list.h>
 #include <utils/identification.h>
-#include <crypto/ietf_attr_list.h>
 
 ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
        "CERT_ALWAYS_SEND",
@@ -96,21 +90,6 @@ struct private_peer_cfg_t {
         */
        identification_t *other_id;
        
-       /**
-        * we have a cert issued by this CA
-        */
-       identification_t *my_ca;
-       
-       /**
-        * we require the other end to have a cert issued by this CA
-        */
-       identification_t *other_ca;
-       
-       /**
-        * we require the other end to belong to at least one group
-        */
-       linked_list_t *groups;
-       
        /**
         * should we send a certificate
         */
@@ -180,6 +159,11 @@ struct private_peer_cfg_t {
         * virtual IP to use remotly
         */
        host_t *other_virtual_ip;
+       
+       /**
+        * required authorization constraints
+        */
+       auth_info_t *auth;
 
 #ifdef P2P     
        /**
@@ -235,12 +219,26 @@ static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
 }
 
 /**
- * Implementation of peer_cfg_t.create_child_cfg_iterator.
+ * Implementation of peer_cfg_t.remove_child_cfg.
  */
-static iterator_t* create_child_cfg_iterator(private_peer_cfg_t *this)
+static void remove_child_cfg(private_peer_cfg_t *this, enumerator_t *enumerator)
 {
-       return this->child_cfgs->create_iterator_locked(this->child_cfgs,
-                                                                                                       &this->mutex);
+       pthread_mutex_lock(&this->mutex);
+       this->child_cfgs->remove_at(this->child_cfgs, enumerator);
+       pthread_mutex_unlock(&this->mutex);
+}
+
+/**
+ * Implementation of peer_cfg_t.create_child_cfg_enumerator.
+ */
+static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this)
+{
+       enumerator_t *enumerator;
+
+       pthread_mutex_lock(&this->mutex);
+       enumerator = this->child_cfgs->create_enumerator(this->child_cfgs);
+       return enumerator_create_cleaner(enumerator,
+                                                                        (void*)pthread_mutex_unlock, &this->mutex);
 }
 
 /**
@@ -267,10 +265,10 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
                                                                         host_t *my_host, host_t *other_host)
 {
        child_cfg_t *current, *found = NULL;
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        
-       iterator = create_child_cfg_iterator(this);
-       while (iterator->iterate(iterator, (void**)&current))
+       enumerator = create_child_cfg_enumerator(this);
+       while (enumerator->enumerate(enumerator, &current))
        {
                if (contains_ts(current, TRUE, my_ts, my_host) &&
                        contains_ts(current, FALSE, other_ts, other_host))
@@ -280,7 +278,7 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
                        break;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        return found;
 }
 
@@ -300,30 +298,6 @@ static identification_t *get_other_id(private_peer_cfg_t *this)
        return this->other_id;
 }
 
-/**
- * Implementation of peer_cfg_t.get_my_ca
- */
-static identification_t *get_my_ca(private_peer_cfg_t *this)
-{
-       return this->my_ca;
-}
-
-/**
- * Implementation of peer_cfg_t.get_other_ca
- */
-static identification_t *get_other_ca(private_peer_cfg_t *this)
-{
-       return this->other_ca;
-}
-
-/**
- * Implementation of peer_cfg_t.get_groups
- */
-static linked_list_t *get_groups(private_peer_cfg_t *this)
-{
-       return this->groups;
-}
-
 /**
  * Implementation of peer_cfg_t.get_cert_policy.
  */
@@ -452,6 +426,14 @@ static host_t* get_other_virtual_ip(private_peer_cfg_t *this, host_t *suggestion
        }
        return suggestion->clone(suggestion);
 }
+       
+/**
+ * Implementation of peer_cfg_t.get_auth.
+ */
+static auth_info_t* get_auth(private_peer_cfg_t *this)
+{
+       return this->auth;
+}
 
 #ifdef P2P
 /**
@@ -502,15 +484,13 @@ static void destroy(private_peer_cfg_t *this)
                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);
-               DESTROY_IF(this->my_ca);
-               DESTROY_IF(this->other_ca);
                DESTROY_IF(this->my_virtual_ip);
                DESTROY_IF(this->other_virtual_ip);
+               this->auth->destroy(this->auth);
 #ifdef P2P
                DESTROY_IF(this->p2p_mediated_by);
                DESTROY_IF(this->peer_id);
 #endif /* P2P */
-               ietfAttr_list_destroy(this->groups);
                free(this->name);
                free(this);
        }
@@ -521,8 +501,7 @@ static void destroy(private_peer_cfg_t *this)
  */
 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,
-                                                       identification_t *my_ca, identification_t *other_ca,
-                                                       linked_list_t *groups, cert_policy_t cert_policy,
+                                                       cert_policy_t cert_policy,
                                                        auth_method_t auth_method, eap_type_t eap_type,
                                                        u_int32_t eap_vendor,
                                                        u_int32_t keyingtries, u_int32_t rekey_time,
@@ -540,13 +519,11 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
        this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version;        
        this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg;
        this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg;
-       this->public.create_child_cfg_iterator = (iterator_t* (*) (peer_cfg_t *))create_child_cfg_iterator;
+       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_my_ca = (identification_t* (*)(peer_cfg_t *))get_my_ca;
-       this->public.get_other_ca = (identification_t* (*)(peer_cfg_t *))get_other_ca;
-       this->public.get_groups = (linked_list_t* (*)(peer_cfg_t *))get_groups;
        this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
        this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
        this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *,u_int32_t*))get_eap_type;
@@ -559,6 +536,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
        this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
        this->public.get_my_virtual_ip = (host_t* (*) (peer_cfg_t *))get_my_virtual_ip;
        this->public.get_other_virtual_ip = (host_t* (*) (peer_cfg_t *, host_t *))get_other_virtual_ip;
+       this->public.get_auth = (auth_info_t*(*)(peer_cfg_t*))get_auth;
        this->public.get_ref = (void(*)(peer_cfg_t *))get_ref;
        this->public.destroy = (void(*)(peer_cfg_t *))destroy;
 #ifdef P2P     
@@ -575,9 +553,6 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
        pthread_mutex_init(&this->mutex, NULL);
        this->my_id = my_id;
        this->other_id = other_id;
-       this->my_ca = my_ca;
-       this->other_ca = other_ca;
-       this->groups = groups;
        this->cert_policy = cert_policy;
        this->auth_method = auth_method;
        this->eap_type = eap_type;
@@ -600,11 +575,15 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
        this->dpd_action = dpd_action;
        this->my_virtual_ip = my_virtual_ip;
        this->other_virtual_ip = other_virtual_ip;
+       this->auth = auth_info_create();
        this->refcount = 1;
 #ifdef P2P
        this->p2p_mediation = p2p_mediation;
        this->p2p_mediated_by = p2p_mediated_by;
        this->peer_id = peer_id;
+#else /* P2P */
+       DESTROY_IF(p2p_mediated_by);
+       DESTROY_IF(peer_id);
 #endif /* P2P */
 
        return &this->public;
index 7f1dbcab6ee91a33cfebbe198e330c6fc77e3338..6c0601ff6da3cd10ec6a0491449d4b8f16d71ded 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file peer_cfg.h
- * 
- * @brief Interface of peer_cfg_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
  * WITHOUT ANY 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 peer_cfg peer_cfg
+ * @{ @ingroup config
  */
 
 #ifndef PEER_CFG_H_
@@ -31,21 +31,20 @@ typedef struct peer_cfg_t peer_cfg_t;
 
 #include <library.h>
 #include <utils/identification.h>
-#include <utils/linked_list.h>
+#include <utils/enumerator.h>
 #include <config/traffic_selector.h>
 #include <config/proposal.h>
 #include <config/ike_cfg.h>
 #include <config/child_cfg.h>
 #include <sa/authenticators/authenticator.h>
 #include <sa/authenticators/eap/eap_method.h>
+#include <credentials/auth_info.h>
 
 /**
  * Certificate sending policy. This is also used for certificate
  * requests when using this definition for the other peer. If
  * it is CERT_NEVER_SEND, a certreq is omitted, otherwise its
  * included.
- *
- * @ingroup config
  * 
  * @warning These definitions must be the same as in pluto/starter,
  * as they are sent over the stroke socket.
@@ -61,17 +60,13 @@ enum cert_policy_t {
 
 /**
  * enum strings for cert_policy_t
- * 
- * @ingroup config
  */
 extern enum_name_t *cert_policy_names;
 
 /**
- * @brief Actions to take when a peer does not respond (dead peer detected).
+ * Actions to take when a peer does not respond (dead peer detected).
  *
  * These values are the same as in pluto/starter, so do not modify them!
- *
- * @ingroup config
  */
 enum dpd_action_t {
        /** DPD disabled */
@@ -90,7 +85,7 @@ enum dpd_action_t {
 extern enum_name_t *dpd_action_names;
 
 /**
- * @brief Configuration of a peer, specified by IDs.
+ * Configuration of a peer, specified by IDs.
  *
  * The peer config defines a connection between two given IDs. It contains
  * exactly one ike_cfg_t, which is use for initiation. Additionally, it contains
@@ -106,61 +101,67 @@ extern enum_name_t *dpd_action_names;
    | - ...         |       | - dpd config      |         | - ...         |-+
    +---------------+       | - ...             |         +---------------+
                            +-------------------+
+                                     ^
+                                     |
+                           +-------------------+
+                           |     auth_info     |
+                           +-------------------+
+                           |     auth_items    |
+                           +-------------------+
    @endverbatim
- *
- * @b Constructors:
- *   - peer_cfg_create()
- *
- * @ingroup config
+ * 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.
  */
 struct peer_cfg_t {
        
        /**
-        * @brief Get the name of the peer_cfg.
+        * Get the name of the peer_cfg.
         * 
         * Returned object is not getting cloned.
         * 
-        * @param this                  calling object
         * @return                              peer_cfg's name
         */
        char* (*get_name) (peer_cfg_t *this);
        
        /**
-        * @brief Get the IKE version to use for initiating.
+        * Get the IKE version to use for initiating.
         *
-        * @param this                  calling object
         * @return                              IKE major version
         */
        u_int (*get_ike_version)(peer_cfg_t *this);
        
        /**
-        * @brief Get the IKE config to use for initiaton.
+        * Get the IKE config to use for initiaton.
         * 
-        * @param this                  calling object
         * @return                              the IKE config to use
         */
        ike_cfg_t* (*get_ike_cfg) (peer_cfg_t *this);
        
        /**
-        * @brief Attach a CHILD config.
+        * Attach a CHILD config.
         * 
-        * @param this                  calling object
         * @param child_cfg             CHILD config to add
         */
        void (*add_child_cfg) (peer_cfg_t *this, child_cfg_t *child_cfg);
        
        /**
-        * @brief Create an iterator for all attached CHILD configs.
+        * Detach a CHILD config, pointed to by an enumerator.
+        *
+        * @param enumerator    enumerator indicating element position
+        */
+       void (*remove_child_cfg)(peer_cfg_t *this, enumerator_t *enumerator);
+       
+       /**
+        * Create an enumerator for all attached CHILD configs.
         * 
-        * @param this                  calling object
-        * @return                              an iterator over all CHILD configs.
+        * @return                              an enumerator over all CHILD configs.
         */
-       iterator_t* (*create_child_cfg_iterator) (peer_cfg_t *this);
+       enumerator_t* (*create_child_cfg_enumerator) (peer_cfg_t *this);
        
        /**
-        * @brief Select a CHILD config from traffic selectors.
+        * Select a CHILD config from traffic selectors.
         * 
-        * @param this                  calling object
         * @param my_ts                 TS for local side
         * @param other_ts              TS for remote side
         * @param my_host               host to narrow down dynamic TS for local side
@@ -172,213 +173,175 @@ struct peer_cfg_t {
                                                                          host_t *other_host);
        
        /**
-        * @brief Get own ID.
+        * Get the authentication constraint items.
+        *
+        * @return                              auth_info object to manipulate requirements
+        */
+       auth_info_t* (*get_auth)(peer_cfg_t *this);
+               
+       /**
+        * Get own ID.
         * 
-        * @param this                  calling object
         * @return                              own id
         */
        identification_t* (*get_my_id)(peer_cfg_t *this);
        
        /**
-        * @brief Get peers ID.
+        * Get peers ID.
         * 
-        * @param this                  calling object
         * @return                              other id
         */
        identification_t* (*get_other_id)(peer_cfg_t *this);
-       
-       /**
-        * @brief Get own CA.
-        * 
-        * @param this                  calling object
-        * @return                              own ca
-        */
-       identification_t* (*get_my_ca)(peer_cfg_t *this);
-
-       /**
-        * @brief Get peer CA.
-        * 
-        * @param this                  calling object
-        * @return                              other ca
-        */
-       identification_t* (*get_other_ca)(peer_cfg_t *this);
-       
-       /**
-        * @brief Get list of group attributes.
-        * 
-        * @param this                  calling object
-        * @return                              linked list of group attributes
-        */
-       linked_list_t* (*get_groups)(peer_cfg_t *this);
 
        /**
-        * @brief Should be sent a certificate for this connection?
+        * Should be sent a certificate for this connection?
         *
-        * @param this          calling object
         * @return                      certificate sending policy
         */
        cert_policy_t (*get_cert_policy) (peer_cfg_t *this);
 
        /**
-        * @brief Get the authentication method to use to authenticate us.
+        * Get the authentication method to use to authenticate us.
         * 
-        * @param this          calling object
         * @return                      authentication method
         */
        auth_method_t (*get_auth_method) (peer_cfg_t *this);
        
        /**
-        * @brief Get the EAP type to use for peer authentication.
+        * Get the EAP type to use for peer authentication.
         *
         * If vendor specific types are used, a vendor ID != 0 is returned to
         * to vendor argument. Then the returned type is specific for that 
         * vendor ID.
         * 
-        * @param this          calling object
         * @param vendor        receives vendor specifier, 0 for predefined EAP types
         * @return                      authentication method
         */
        eap_type_t (*get_eap_type) (peer_cfg_t *this, u_int32_t *vendor);
        
        /**
-        * @brief Get the max number of retries after timeout.
+        * Get the max number of retries after timeout.
         *
-        * @param this          calling object
         * @return                      max number retries
         */
        u_int32_t (*get_keyingtries) (peer_cfg_t *this);
        
        /**
-        * @brief Get a time to start rekeying (is randomized with jitter).
+        * Get a time to start rekeying (is randomized with jitter).
         *
-        * @param this          calling object
         * @return                      time in s when to start rekeying, 0 disables rekeying
         */
        u_int32_t (*get_rekey_time)(peer_cfg_t *this);
        
        /**
-        * @brief Get a time to start reauthentication (is randomized with jitter).
+        * Get a time to start reauthentication (is randomized with jitter).
         *
-        * @param this          calling object
         * @return                      time in s when to start reauthentication, 0 disables it
         */
        u_int32_t (*get_reauth_time)(peer_cfg_t *this);
        
        /**
-        * @brief Get the timeout of a rekeying/reauthenticating SA.
+        * Get the timeout of a rekeying/reauthenticating SA.
         *
-        * @param thsi          calling object
         * @return                      timeout in s
         */
        u_int32_t (*get_over_time)(peer_cfg_t *this);
        
        /**
-        * @brief Use MOBIKE (RFC4555) if peer supports it?
+        * Use MOBIKE (RFC4555) if peer supports it?
         * 
-        * @param this          calling object
         * @return                      TRUE to enable MOBIKE support
         */
        bool (*use_mobike) (peer_cfg_t *this);
        
        /**
-        * @brief Get the DPD check interval.
+        * Get the DPD check interval.
         * 
-        * @param this          calling object
         * @return                      dpd_delay in seconds
         */
        u_int32_t (*get_dpd_delay) (peer_cfg_t *this);
        
        /**
-        * @brief What should be done with a CHILD_SA, when other peer does not respond.
+        * What should be done with a CHILD_SA, when other peer does not respond.
         *
-        * @param this          calling object
         * @return                      dpd action
         */     
        dpd_action_t (*get_dpd_action) (peer_cfg_t *this);
        
        /**
-        * @brief Get a virtual IP for the local peer.
+        * Get a virtual IP for the local peer.
         *
         * If no virtual IP should be used, NULL is returned. %any means to request
         * a virtual IP using configuration payloads. A specific address is also
         * used for a request and may be changed by the server.
         *
-        * @param this                  peer_cfg
         * @param suggestion    NULL, %any or specific
         * @return                              clone of an IP, %any or NULL
         */
        host_t* (*get_my_virtual_ip) (peer_cfg_t *this);
        
        /**
-        * @brief Get a virtual IP for the remote peer.
+        * Get a virtual IP for the remote peer.
         *
         * An IP may be supplied, if one was requested by the initiator. However,
         * the suggestion is not more as it says, any address may be returned, even
         * NULL to not use virtual IPs.
         *
-        * @param this                  peer_cfg
         * @param suggestion    NULL, %any or specific
         * @return                              clone of an IP to use
         */
        host_t* (*get_other_virtual_ip) (peer_cfg_t *this, host_t *suggestion);
-
+       
 #ifdef P2P     
        /**
-        * @brief Is this a mediation connection?
+        * Is this a mediation connection?
         * 
-        * @param this                  peer_cfg
         * @return                              TRUE, if this is a mediation connection
         */
        bool (*is_mediation) (peer_cfg_t *this);
        
        /**
-        * @brief Get peer_cfg of the connection this one is mediated through.
+        * Get peer_cfg of the connection this one is mediated through.
         * 
-        * @param this                  peer_cfg
         * @return                              reference to peer_cfg of the mediation connection
         */
        peer_cfg_t* (*get_mediated_by) (peer_cfg_t *this);
        
        /**
-        * @brief Get the id of the other peer at the mediation server.
+        * Get the id of the other peer at the mediation server.
         * 
         * This is the leftid of the peer's connection with the mediation server.
         * 
         * If it is not configured, it is assumed to be the same as the right id
         * of this connection. 
         * 
-        * @param this                  peer_cfg
         * @return                              the id of the other peer
         */
        identification_t* (*get_peer_id) (peer_cfg_t *this);
 #endif /* P2P */
        
        /**
-        * @brief Get a new reference.
+        * Get a new reference.
         *
         * Get a new reference to this peer_cfg by increasing
         * it's internal reference counter.
         * Do not call get_ref or any other function until you
         * already have a reference. Otherwise the object may get
         * destroyed while calling get_ref(),
-        * 
-        * @param this                          calling object
         */
        void (*get_ref) (peer_cfg_t *this);
        
        /**
-        * @brief Destroys the peer_cfg object.
+        * Destroys the peer_cfg object.
         *
         * Decrements the internal reference counter and
         * destroys the peer_cfg when it reaches zero.
-        * 
-        * @param this                          calling object
         */
        void (*destroy) (peer_cfg_t *this);
 };
 
 /**
- * @brief Create a configuration object for IKE_AUTH and later.
+ * Create a configuration object for IKE_AUTH and later.
  * 
  * name-string gets cloned, ID's not.
  * Virtual IPs are used if they are != NULL. A %any host means the virtual
@@ -392,9 +355,6 @@ struct peer_cfg_t {
  * @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 my_ca                                CA to use for us
- * @param other_ca                     CA to use for other
- * @param groups                       list of group memberships
  * @param cert_policy          should we send a certificate payload?
  * @param auth_method          auth method to use to authenticate us
  * @param eap_type                     EAP type to use for peer authentication
@@ -414,13 +374,10 @@ struct peer_cfg_t {
  * @param p2p_mediated_by      name of the mediation connection to mediate through
  * @param peer_id                      ID that identifies our peer at the mediation server
  * @return                                     peer_cfg_t object
- * 
- * @ingroup config
  */
 peer_cfg_t *peer_cfg_create(char *name, u_int ikev_version, ike_cfg_t *ike_cfg,
                                                        identification_t *my_id, identification_t *other_id,
-                                                       identification_t *my_ca, identification_t *other_ca,
-                                                       linked_list_t *groups, cert_policy_t cert_policy,
+                                                       cert_policy_t cert_policy,
                                                        auth_method_t auth_method, eap_type_t eap_type,
                                                        u_int32_t eap_vendor,
                                                        u_int32_t keyingtries, u_int32_t rekey_time,
@@ -431,4 +388,4 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ikev_version, ike_cfg_t *ike_cfg,
                                                        bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
                                                        identification_t *peer_id);
 
-#endif /* PEER_CFG_H_ */
+#endif /* PEER_CFG_H_ @} */
index cff9859c12fddf569c3b930a42aa61c63f6c50ff..04ec28a61e9013c2bcf6512919dc43fc7ec0b9f0 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file proposal.c
- * 
- * @brief Implementation of proposal_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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>
index 379550f446799d65bdaef160dae8788bf3585fc8..0f3559012b879ac54c39cc3ff51aa08d465b0591 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file proposal.h
- *
- * @brief Interface of proposal_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 proposal proposal
+ * @{ @ingroup config
  */
 
 #ifndef PROPOSAL_H_
@@ -40,8 +40,6 @@ typedef struct proposal_t proposal_t;
 
 /**
  * Protocol ID of a proposal.
- *
- * @ingroup config
  */
 enum protocol_id_t {
        PROTO_NONE = 0,
@@ -52,16 +50,12 @@ enum protocol_id_t {
 
 /**
  * enum names for protocol_id_t
- *
- * @ingroup config
  */
 extern enum_name_t *protocol_id_names;
 
 
 /**
  * Type of a transform, as in IKEv2 RFC 3.3.2.
- *
- * @ingroup config
  */
 enum transform_type_t {
        UNDEFINED_TRANSFORM_TYPE = 241,
@@ -74,16 +68,12 @@ enum transform_type_t {
 
 /**
  * enum names for transform_type_t.
- *
- * @ingroup config
  */
 extern enum_name_t *transform_type_names;
 
 
 /**
  * Extended sequence numbers, as in IKEv2 RFC 3.3.2.
- *
- * @ingroup config
  */
 enum extended_sequence_numbers_t {
        NO_EXT_SEQ_NUMBERS = 0,
@@ -92,8 +82,6 @@ enum extended_sequence_numbers_t {
 
 /**
  * enum strings for extended_sequence_numbers_t.
- *
- * @ingroup config
  */
 extern enum_name_t *extended_sequence_numbers_names;
 
@@ -102,8 +90,6 @@ extern enum_name_t *extended_sequence_numbers_names;
 /**
  * Struct used to store different kinds of algorithms. The internal
  * lists of algorithms contain such structures.
- *
- * @ingroup config
  */
 struct algorithm_t {
        /**
@@ -118,22 +104,17 @@ struct algorithm_t {
 };
 
 /**
- * @brief Stores a set of algorithms used for an SA.
+ * Stores a set of algorithms used for an SA.
  * 
  * A proposal stores algorithms for a specific 
  * protocol. It can store algorithms for one protocol.
  * Proposals with multiple protocols are not supported,
  * as it's not specified in RFC4301 anymore.
- * 
- * @b Constructors:
- *   - proposal_create()
- * 
- * @ingroup config
  */
 struct proposal_t {
        
        /**
-        * @brief Add an algorithm to the proposal.
+        * Add an algorithm to the proposal.
         * 
         * The algorithms are stored by priority, first added
         * is the most preferred.
@@ -144,120 +125,103 @@ struct proposal_t {
         * integrity_algorithm_t, dh_group_number_t and
         * extended_sequence_numbers_t.
         * 
-        * @param this                                  calling object
-        * @param type                                  kind of algorithm
-        * @param alg                                   identifier for algorithm
-        * @param key_size                              key size to use
+        * @param type                  kind of algorithm
+        * @param alg                   identifier for algorithm
+        * @param key_size              key size to use
         */
        void (*add_algorithm) (proposal_t *this, transform_type_t type, u_int16_t alg, size_t key_size);
        
        /**
-        * @brief Get an iterator over algorithms for a specifc algo type.
+        * Get an iterator over algorithms for a specifc algo type.
         * 
-        * @param this                                  calling object
-        * @param type                                  kind of algorithm
-        * @return                                              iterator over algorithm_t's
+        * @param type                  kind of algorithm
+        * @return                              iterator over algorithm_t's
         */
        iterator_t *(*create_algorithm_iterator) (proposal_t *this, transform_type_t type);
        
        /**
-        * @brief Get the algorithm for a type to use.
+        * Get the algorithm for a type to use.
         * 
         * If there are multiple algorithms, only the first is returned.
         * 
-        * @param this                                  calling object
-        * @param type                                  kind of algorithm
-        * @param[out] algo                             pointer which receives algorithm and key size
-        * @return                                              TRUE if algorithm of this kind available
+        * @param type                  kind of algorithm
+        * @param algo                  pointer which receives algorithm and key size
+        * @return                              TRUE if algorithm of this kind available
         */
        bool (*get_algorithm) (proposal_t *this, transform_type_t type, algorithm_t** algo);
        
        /**
-        * @brief Check if the proposal has a specific DH group.
+        * Check if the proposal has a specific DH group.
         * 
-        * @param this                                  calling object
-        * @param group                                 group to check for
-        * @return                                              TRUE if algorithm included
+        * @param group                 group to check for
+        * @return                              TRUE if algorithm included
         */
        bool (*has_dh_group) (proposal_t *this, diffie_hellman_group_t group);
 
        /**
-        * @brief Compare two proposal, and select a matching subset.
+        * Compare two proposal, and select a matching subset.
         * 
         * If the proposals are for the same protocols (AH/ESP), they are
         * compared. If they have at least one algorithm of each type
         * in common, a resulting proposal of this kind is created.
         * 
-        * @param this                                  calling object
-        * @param other                                 proposal to compair agains
-        * @return                                              
-        *                                                              - selected proposal, if possible
-        *                                                              - NULL, if proposals don't match
+        * @param other                 proposal to compair agains
+        * @return                              selected proposal, NULL if proposals don't match
         */
        proposal_t *(*select) (proposal_t *this, proposal_t *other);
        
        /**
-        * @brief Get the protocol ID of the proposal.
+        * Get the protocol ID of the proposal.
         *
-        * @param this                          calling object
-        * @return                                      protocol of the proposal
+        * @return                              protocol of the proposal
         */
        protocol_id_t (*get_protocol) (proposal_t *this);
        
        /**
-        * @brief Get the SPI of the proposal.
+        * Get the SPI of the proposal.
         * 
-        * @param this                          calling object
-        * @return                                      spi for proto
+        * @return                              spi for proto
         */
        u_int64_t (*get_spi) (proposal_t *this);
        
        /**
-        * @brief Set the SPI of the proposal.
+        * Set the SPI of the proposal.
         * 
-        * @param this                          calling object
-        * @param spi                           spi to set for proto
+        * @param spi                   spi to set for proto
         */
        void (*set_spi) (proposal_t *this, u_int64_t spi);
        
        /**
-        * @brief Clone a proposal.
+        * Clone a proposal.
         * 
-        * @param this                          proposal to clone
-        * @return                                      clone of it
+        * @return                              clone of proposal
         */
        proposal_t *(*clone) (proposal_t *this);
        
        /**
-        * @brief Destroys the proposal object.
-        * 
-        * @param this                          calling object
+        * Destroys the proposal object.
         */
        void (*destroy) (proposal_t *this);
 };
 
 /**
- * @brief Create a child proposal for AH, ESP or IKE.
+ * Create a child proposal for AH, ESP or IKE.
  *
  * @param protocol                     protocol, such as PROTO_ESP
  * @return                                     proposal_t object
- *
- * @ingroup config
  */
 proposal_t *proposal_create(protocol_id_t protocol);
 
 /**
- * @brief Create a default proposal if nothing further specified.
+ * Create a default proposal if nothing further specified.
  *
  * @param protocol                     protocol, such as PROTO_ESP
  * @return                                     proposal_t object
- *
- * @ingroup config
  */
 proposal_t *proposal_create_default(protocol_id_t protocol);
 
 /**
- * @brief Create a proposal from a string identifying the algorithms.
+ * Create a proposal from a string identifying the algorithms.
  *
  * The string is in the same form as a in the ipsec.conf file.
  * E.g.:       aes128-sha2_256-modp2048
@@ -268,9 +232,7 @@ proposal_t *proposal_create_default(protocol_id_t protocol);
  * @param protocol                     protocol, such as PROTO_ESP
  * @param algs                         algorithms as string
  * @return                                     proposal_t object
- * 
- * @ingroup config
  */
 proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs);
 
-#endif /* PROPOSAL_H_ */
+#endif /* PROPOSAL_H_ @} */
index da39c434d4bf50a5044433deddcc5f15fcfbdfee..02a74a1b7fe9344d5733cb03d7e9c463f79d8ed0 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file traffic_selector.c
- * 
- * @brief Implementation of traffic_selector_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2007 Martin Willi
@@ -20,6 +13,8 @@
  * WITHOUT ANY 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 <arpa/inet.h>
@@ -276,11 +271,25 @@ static int print(FILE *stream, const struct printf_info *info,
 }
 
 /**
- * register printf() handlers
+ * arginfo handler for printf() traffic selector
+ */
+static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+       if (n > 0)
+       {
+               argtypes[0] = PA_POINTER;
+       }
+       return 1;
+}
+
+/**
+ * return printf hook functions for a chunk
  */
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t traffic_selector_get_printf_hooks()
 {
-       register_printf_function(PRINTF_TRAFFIC_SELECTOR, print, arginfo_ptr);
+       printf_hook_functions_t hooks = {print, arginfo};
+       
+       return hooks;
 }
 
 /**
index 0e798fc6aab73419e6bda8c689fc29b00f001c98..4b8b91ac7724c0253caed878a7a7b5c5b38edb46 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file traffic_selector.h
- * 
- * @brief Interface of traffic_selector_t.
- *  
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * WITHOUT ANY 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 traffic_selector traffic_selector
+ * @{ @ingroup config
  */
 
 #ifndef TRAFFIC_SELECTOR_H_
@@ -33,8 +33,6 @@ typedef struct traffic_selector_t traffic_selector_t;
 
 /**
  * Traffic selector types.
- * 
- * @ingroup config
  */
 enum ts_type_t {
        
@@ -63,29 +61,20 @@ enum ts_type_t {
 extern enum_name_t *ts_type_name;
 
 /**
- * @brief Object representing a traffic selector entry.
+ * Object representing a traffic selector entry.
  *
  * A traffic selector defines an range of addresses
  * and a range of ports. IPv6 is not fully supported yet.
- *
- * @b Constructors:
- * - traffic_selector_create_from_bytes()
- * - traffic_selector_create_from_string()
- *
- * @todo Add IPv6 support
- *
- * @ingroup config
  */
 struct traffic_selector_t {
        
        /**
-        * @brief Compare two traffic selectors, and create a new one
+        * Compare two traffic selectors, and create a new one
         * which is the largest subset of both (subnet & port).
         *
         * Resulting traffic_selector is newly created and must be destroyed.
         *
-        * @param this          first to compare
-        * @param other         second to compare
+        * @param other         traffic selector to compare
         * @return
         *                                      - created subset of them
         *                                      - or NULL if no match between this and other
@@ -94,73 +83,66 @@ struct traffic_selector_t {
                                                                                traffic_selector_t *other);
        
        /**
-        * @brief Clone a traffic selector.
+        * Clone a traffic selector.
         *
-        * @param this          traffic selector to clone
         * @return                      clone of it
         */
        traffic_selector_t *(*clone) (traffic_selector_t *this);
        
        /**
-        * @brief Get starting address of this ts as a chunk.
+        * Get starting address of this ts as a chunk.
         *
         * Chunk is in network order gets allocated.
         *
-        * @param this          called object
         * @return                      chunk containing the address
         */
        chunk_t (*get_from_address) (traffic_selector_t *this);
        
        /**
-        * @brief Get ending address of this ts as a chunk.
+        * Get ending address of this ts as a chunk.
         *
         * Chunk is in network order gets allocated.
         *
-        * @param this          called object
         * @return                      chunk containing the address
         */
        chunk_t (*get_to_address) (traffic_selector_t *this);
        
        /**
-        * @brief Get starting port of this ts.
+        * Get starting port of this ts.
         * 
         * Port is in host order, since the parser converts it.
         * Size depends on protocol.
         *  
-        * @param this          called object
         * @return                      port
         */
        u_int16_t (*get_from_port) (traffic_selector_t *this);
        
        /**
-        * @brief Get ending port of this ts.
+        * Get ending port of this ts.
         *
         * Port is in host order, since the parser converts it.
         * Size depends on protocol.
         *
-        * @param this          called object
         * @return                      port
         */
        u_int16_t (*get_to_port) (traffic_selector_t *this);
        
        /**
-        * @brief Get the type of the traffic selector.
+        * Get the type of the traffic selector.
         *
-        * @param this          called object
         * @return                      ts_type_t specifying the type
         */
        ts_type_t (*get_type) (traffic_selector_t *this);
        
        /**
-        * @brief Get the protocol id of this ts.
+        * Get the protocol id of this ts.
         *
-        * @param this          called object
         * @return                      protocol id
         */
        u_int8_t (*get_protocol) (traffic_selector_t *this);
        
        /**
-        * @brief Check if the traffic selector is for a single host.
+        * Check if the traffic selector is for a single host.
         *
         * Traffic selector may describe the end of *-to-host tunnel. In this
         * case, the address range is a single address equal to the hosts
@@ -168,61 +150,54 @@ struct traffic_selector_t {
         * If host is NULL, the traffic selector is checked if it is a single host,
         * but not a specific one.
         *
-        * @param this          called object
         * @param host          host_t specifying the address range
         */
        bool (*is_host) (traffic_selector_t *this, host_t* host);
        
        /**
-        * @brief Update the address of a traffic selector.
+        * Update the address of a traffic selector.
         *
         * Update the address range of a traffic selector, if it is
         * constructed with the traffic_selector_create_dynamic().
         *
-        * @param this          called object
         * @param host          host_t specifying the address
         */
        void (*set_address) (traffic_selector_t *this, host_t* host);
        
        /**
-        * @brief Compare two traffic selectors for equality.
+        * Compare two traffic selectors for equality.
         * 
-        * @param this          first to compare
-        * @param other         second to compare with first
+        * @param other         ts to compare with this
         * @return                      pointer to a string.
         */
        bool (*equals) (traffic_selector_t *this, traffic_selector_t *other);
        
        /**
-        * @brief Check if a traffic selector is contained completly in another.
+        * Check if a traffic selector is contained completly in another.
         *
         * contains() allows to check if multiple traffic selectors are redundant.
         *
-        * @param this          ts that is contained in another
         * @param other         ts that contains this
         * @return                      TRUE if other contains this completly, FALSE otherwise
         */
        bool (*is_contained_in) (traffic_selector_t *this, traffic_selector_t *other);
 
        /**
-        * @brief Check if a specific host is included in the address range of 
+        * Check if a specific host is included in the address range of 
         * this traffic selector.
         *
-        * @param this          called object
         * @param host          the host to check
         */
        bool (*includes) (traffic_selector_t *this, host_t *host);
        
        /**
-        * @brief Destroys the ts object
-        *
-        * @param this          called object
+        * Destroys the ts object
         */
        void (*destroy) (traffic_selector_t *this);
 };
 
 /**
- * @brief Create a new traffic selector using human readable params.
+ * Create a new traffic selector using human readable params.
  * 
  * @param protocol             protocol for this ts, such as TCP or UDP
  * @param type                 type of following addresses, such as TS_IPV4_ADDR_RANGE
@@ -233,8 +208,6 @@ struct traffic_selector_t {
  * @return
  *                                             - traffic_selector_t object
  *                                             - NULL if invalid address strings/protocol
- * 
- * @ingroup config
  */
 traffic_selector_t *traffic_selector_create_from_string(
                                                                        u_int8_t protocol, ts_type_t type,
@@ -242,7 +215,7 @@ traffic_selector_t *traffic_selector_create_from_string(
                                                                        char *to_addr, u_int16_t to_port);
 
 /**
- * @brief Create a new traffic selector using data read from the net.
+ * Create a new traffic selector using data read from the net.
  * 
  * There exists a mix of network and host order in the params.
  * But the parser gives us this data in this format, so we
@@ -255,8 +228,6 @@ traffic_selector_t *traffic_selector_create_from_string(
  * @param to_address   end of address range as string, network
  * @param to_port              port number, host order
  * @return                             traffic_selector_t object
- *
- * @ingroup config
  */
 traffic_selector_t *traffic_selector_create_from_bytes(
                                                                u_int8_t protocol, ts_type_t type,
@@ -264,7 +235,7 @@ traffic_selector_t *traffic_selector_create_from_bytes(
                                                                chunk_t to_address, u_int16_t to_port);
 
 /**
- * @brief Create a new traffic selector defining a whole subnet.
+ * Create a new traffic selector defining a whole subnet.
  * 
  * In most cases, definition of a traffic selector for full subnets
  * is sufficient. This constructor creates a traffic selector for
@@ -278,15 +249,13 @@ traffic_selector_t *traffic_selector_create_from_bytes(
  * @return
  *                                             - traffic_selector_t object
  *                                             - NULL if address family of net not supported
- *
- * @ingroup config
  */
 traffic_selector_t *traffic_selector_create_from_subnet(
                                                                        host_t *net, u_int8_t netbits, 
                                                                        u_int8_t protocol, u_int16_t port);
 
 /**
- * @brief Create a traffic selector for host-to-host cases.
+ * Create a traffic selector for host-to-host cases.
  * 
  * For host2host or virtual IP setups, the traffic selectors gets
  * created at runtime using the external/virtual IP. Using this constructor,
@@ -300,13 +269,19 @@ traffic_selector_t *traffic_selector_create_from_subnet(
  * @return
  *                                             - traffic_selector_t object
  *                                             - NULL if type not supported
- *
- * @ingroup config
  */
 traffic_selector_t *traffic_selector_create_dynamic(
                                                                        u_int8_t protocol, ts_type_t type,
                                                                        u_int16_t from_port, u_int16_t to_port);
 
-#endif /* TRAFFIC_SELECTOR_H_ */
+/**
+ * Get printf hooks for a traffic selector.
+ *
+ * Arguments are: 
+ *    traffic_selector_t *ts
+ * With the #-specifier, arguments are:
+ *    linked_list_t *list containing traffic_selector_t*
+ */
+printf_hook_functions_t traffic_selector_get_printf_hooks();
 
-/* vim: set ts=4 sw=4 noet: */
+#endif /* TRAFFIC_SELECTOR_H_ @} */
similarity index 72%
rename from src/charon/control/interface_manager.c
rename to src/charon/control/controller.c
index 4d5aa2ea64c676c8a70d908abf361da82ddf0821..353b35780899904309b283bad9dbefe7e68bf3f1 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file interface_manager.c
- * 
- * @brief Implementation of interface_manager_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 "interface_manager.h"
+#include "controller.h"
 
 #include <sys/types.h>
 #include <dirent.h>
 
 #include <daemon.h>
 #include <library.h>
-#include <control/interfaces/interface.h>
 
 
-typedef struct private_interface_manager_t private_interface_manager_t;
+typedef struct private_controller_t private_controller_t;
 typedef struct interface_bus_listener_t interface_bus_listener_t;
 
 /**
  * Private data of an stroke_t object.
  */
-struct private_interface_manager_t {
+struct private_controller_t {
 
        /**
         * Public part of stroke_t object.
         */
-       interface_manager_t public;
-       
-       /**
-        * a list of all loaded interfaces
-        */
-       linked_list_t *interfaces;
-       
-       /**
-        * dlopen() handles of interfaces
-        */
-       linked_list_t *handles;
+       controller_t public;
 };
 
 
@@ -80,7 +64,7 @@ struct interface_bus_listener_t {
        /**
         *  interface callback (listener gets redirected to here)
         */
-       interface_manager_cb_t callback;
+       controller_cb_t callback;
        
        /**
         * user parameter to pass to callback
@@ -130,9 +114,9 @@ static void nop(job_t *job)
 }
 
 /**
- * Implementation of interface_manager_t.create_ike_sa_iterator.
+ * Implementation of controller_t.create_ike_sa_iterator.
  */
-static iterator_t* create_ike_sa_iterator(interface_manager_t *this)
+static iterator_t* create_ike_sa_iterator(controller_t *this)
 {
        return charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
 }
@@ -173,11 +157,11 @@ static status_t initiate_execute(interface_job_t *job)
        ike_sa_t *ike_sa;
        interface_bus_listener_t *listener = &job->listener;
        peer_cfg_t *peer_cfg = listener->peer_cfg;
-
+       
        ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
                                                                                                                peer_cfg);
        listener->ike_sa = ike_sa;
-
+       
        if (ike_sa->get_peer_cfg(ike_sa) == NULL)
        {
                ike_sa->set_peer_cfg(ike_sa, peer_cfg);
@@ -193,11 +177,11 @@ static status_t initiate_execute(interface_job_t *job)
 }
 
 /**
- * Implementation of interface_manager_t.initiate.
+ * Implementation of controller_t.initiate.
  */
-static status_t initiate(private_interface_manager_t *this,
+static status_t initiate(private_controller_t *this,
                                                 peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
-                                                interface_manager_cb_t callback, void *param)
+                                                controller_cb_t callback, void *param)
 {
        interface_job_t job;
 
@@ -273,10 +257,10 @@ static status_t terminate_ike_execute(interface_job_t *job)
 }
 
 /**
- * Implementation of interface_manager_t.terminate_ike.
+ * Implementation of controller_t.terminate_ike.
  */
-static status_t terminate_ike(interface_manager_t *this, u_int32_t unique_id, 
-                                                         interface_manager_cb_t callback, void *param)
+static status_t terminate_ike(controller_t *this, u_int32_t unique_id, 
+                                                         controller_cb_t callback, void *param)
 {
        interface_job_t job;
        
@@ -375,10 +359,10 @@ static status_t terminate_child_execute(interface_job_t *job)
 }
 
 /**
- * Implementation of interface_manager_t.terminate_child.
+ * Implementation of controller_t.terminate_child.
  */
-static status_t terminate_child(interface_manager_t *this, u_int32_t reqid, 
-                                                               interface_manager_cb_t callback, void *param)
+static status_t terminate_child(controller_t *this, u_int32_t reqid, 
+                                                               controller_cb_t callback, void *param)
 {
        interface_job_t job;
        
@@ -434,7 +418,6 @@ static status_t route_execute(interface_job_t *job)
        ike_sa_t *ike_sa;
        interface_bus_listener_t *listener = &job->listener;
        peer_cfg_t *peer_cfg = listener->peer_cfg;
-       
        ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
                                                                                                                peer_cfg);
        listener->ike_sa = ike_sa;
@@ -452,11 +435,11 @@ static status_t route_execute(interface_job_t *job)
 }
 
 /**
- * Implementation of interface_manager_t.route.
+ * Implementation of controller_t.route.
  */
-static status_t route(interface_manager_t *this,
+static status_t route(controller_t *this,
                                          peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
-                                         interface_manager_cb_t callback, void *param)
+                                         controller_cb_t callback, void *param)
 {
        interface_job_t job;
        
@@ -530,10 +513,10 @@ static status_t unroute_execute(interface_job_t *job)
 }
 
 /**
- * Implementation of interface_manager_t.unroute.
+ * Implementation of controller_t.unroute.
  */
-static status_t unroute(interface_manager_t *this, u_int32_t reqid, 
-                                               interface_manager_cb_t callback, void *param)
+static status_t unroute(controller_t *this, u_int32_t reqid, 
+                                               controller_cb_t callback, void *param)
 {
        interface_job_t job;
        
@@ -554,77 +537,10 @@ static status_t unroute(interface_manager_t *this, u_int32_t reqid,
        return job.listener.status;
 }
 
-/**
- * load the control interface modules
- */
-static void load_interfaces(private_interface_manager_t *this)
-{
-       struct dirent* entry;
-       DIR* dir;
-
-       dir = opendir(IPSEC_INTERFACEDIR);
-       if (dir == NULL)
-       {
-               DBG1(DBG_CFG, "error opening interface modules directory "IPSEC_INTERFACEDIR);
-               return;
-       }
-       
-       DBG1(DBG_CFG, "loading control interface modules from '"IPSEC_INTERFACEDIR"'");
-
-       while ((entry = readdir(dir)) != NULL)
-       {
-               char file[256];
-               interface_t *interface;
-               interface_constructor_t constructor;
-               void *handle;
-               char *ending;
-               
-               snprintf(file, sizeof(file), IPSEC_INTERFACEDIR"/%s", entry->d_name);
-               
-               ending = entry->d_name + strlen(entry->d_name) - 3;
-               if (ending <= entry->d_name || !streq(ending, ".so"))
-               {
-                       /* skip anything which does not look like a library */
-                       DBG2(DBG_CFG, "  skipping %s, doesn't look like a library",
-                                entry->d_name);
-                       continue;
-               }
-               /* try to load the library */
-               handle = dlopen(file, RTLD_LAZY);
-               if (handle == NULL)
-               {
-                       DBG1(DBG_CFG, "  opening control interface module %s failed: %s",
-                                entry->d_name, dlerror());
-                       continue;
-               }
-               constructor = dlsym(handle, "interface_create");
-               if (constructor == NULL)
-               {
-                       DBG1(DBG_CFG, "  interface module %s has no interface_create() "
-                                "function, skipped", entry->d_name);
-                       dlclose(handle);
-                       continue;
-               }
-               
-               interface = constructor();
-               if (interface == NULL)
-               {
-                       DBG1(DBG_CFG, "  unable to create instance of interface "
-                                "module %s, skipped", entry->d_name);
-                       dlclose(handle);
-                       continue;
-               }
-               DBG1(DBG_CFG, "  loaded control interface module successfully from %s", entry->d_name);
-               this->interfaces->insert_last(this->interfaces, interface);
-               this->handles->insert_last(this->handles, handle);
-       }
-       closedir(dir);
-}
-
 /**
  * See header
  */
-bool interface_manager_cb_empty(void *param, signal_t signal, level_t level,
+bool controller_cb_empty(void *param, signal_t signal, level_t level,
                                                                ike_sa_t *ike_sa, char *format, va_list args)
 {
        return TRUE;
@@ -633,32 +549,25 @@ bool interface_manager_cb_empty(void *param, signal_t signal, level_t level,
 /**
  * Implementation of stroke_t.destroy.
  */
-static void destroy(private_interface_manager_t *this)
+static void destroy(private_controller_t *this)
 {
-       this->interfaces->destroy_offset(this->interfaces, offsetof(interface_t, destroy));
-       this->handles->destroy_function(this->handles, (void*)dlclose);
        free(this);
 }
 
 /*
  * Described in header-file
  */
-interface_manager_t *interface_manager_create(void)
+controller_t *controller_create(void)
 {
-       private_interface_manager_t *this = malloc_thing(private_interface_manager_t);
-       
-       this->public.create_ike_sa_iterator = (iterator_t*(*)(interface_manager_t*))create_ike_sa_iterator;
-       this->public.initiate = (status_t(*)(interface_manager_t*,peer_cfg_t*,child_cfg_t*,bool(*)(void*,signal_t,level_t,ike_sa_t*,char*,va_list),void*))initiate;
-       this->public.terminate_ike = (status_t(*)(interface_manager_t*,u_int32_t,interface_manager_cb_t, void*))terminate_ike;
-       this->public.terminate_child = (status_t(*)(interface_manager_t*,u_int32_t,interface_manager_cb_t, void *param))terminate_child;
-       this->public.route = (status_t(*)(interface_manager_t*,peer_cfg_t*, child_cfg_t*,interface_manager_cb_t,void*))route;
-       this->public.unroute = (status_t(*)(interface_manager_t*,u_int32_t,interface_manager_cb_t,void*))unroute;
-       this->public.destroy = (void (*)(interface_manager_t*))destroy;
-       
-       this->interfaces = linked_list_create();
-       this->handles = linked_list_create();
+       private_controller_t *this = malloc_thing(private_controller_t);
        
-       load_interfaces(this);
+       this->public.create_ike_sa_iterator = (iterator_t*(*)(controller_t*))create_ike_sa_iterator;
+       this->public.initiate = (status_t(*)(controller_t*,peer_cfg_t*,child_cfg_t*,bool(*)(void*,signal_t,level_t,ike_sa_t*,char*,va_list),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;
 }
similarity index 55%
rename from src/charon/control/interface_manager.h
rename to src/charon/control/controller.h
index 3ee1f0e39bab399213bf18629a27c8f80842e213..460c04e0de994053e8b8810c757b86147daa36a0 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file interface_manager.h
- *
- * @brief Interface of interface_manager_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 INTERFACE_MANAGER_H_
-#define INTERFACE_MANAGER_H_
+/**
+ * @defgroup controller_i controller
+ * @{ @ingroup control
+ */
+
+#ifndef CONTROLLER_H_
+#define CONTROLLER_H_
 
 #include <bus/bus.h>
 
 /**
- * callback to log things triggered by interface_manager.
+ * callback to log things triggered by controller.
  *
  * @param param                        echoed parameter supplied when function invoked
  * @param signal               type of signal
  * @param format               printf like format string
  * @param args                 list of arguments to use for format
  * @return                             FALSE to return from invoked function
- * @ingroup control
  */
-typedef bool(*interface_manager_cb_t)(void* param, signal_t signal, level_t level,
+typedef bool(*controller_cb_t)(void* param, signal_t signal, level_t level,
                                                           ike_sa_t* ike_sa, char* format, va_list args);
 
 /**
- * @brief Empty callback function for interface_manager_t functions.
+ * Empty callback function for controller_t functions.
  *
  * If you wan't to do a syncrhonous call, but don't need a callback, pass
- * this function to the interface_managers methods.
+ * this function to the controllers methods.
  */
-bool interface_manager_cb_empty(void *param, signal_t signal, level_t level,
+bool controller_cb_empty(void *param, signal_t signal, level_t level,
                                                                ike_sa_t *ike_sa, char *format, va_list args);
 
-typedef struct interface_manager_t interface_manager_t;
+typedef struct controller_t controller_t;
 
 /**
- * @brief The interface_manager loads control interfaces and has helper methods.
+ * The controller provides a simple interface to run actions.
  *
- * One job of the interface manager is to load pluggable control interface
- * modules, implemented as interface_t.
- * @verbatim
-
-   +---------+      +------------+         +--------------+     |
-   |         |      |            |<----- +--------------+ |     |
-   | daemon  |<-----| interface- |     +--------------+ |-+  <==|==> IPC
-   |  core   |      | manager    |<----|  interfaces  |-+       |
-   |         |<-----|            |     +--------------+         |
-   |         |      |            |                              |
-   +---------+      +------------+                              |
-
-   @endverbatim
- * The manager does not really use the interfaces, instead, the interface
- * use the manager to fullfill their tasks (initiating, terminating, ...). 
- * The interface_manager starts actions by creating jobs. It then tries to
+ * The controller starts actions by creating jobs. It then tries to
  * evaluate the result of the operation by listening on the bus.
  *
  * Passing NULL as callback to the managers function calls them asynchronously.
  * If a callback is specified, they are called synchronoulsy. There is a default
- * callback "interface_manager_cb_empty" if you wan't to call a function
+ * callback "controller_cb_empty" if you wan't to call a function
  * synchronously, but don't need a callback.
- * 
- * @b Constructors:
- * - interface_manager_create()
- * 
- * @ingroup control
  */
-struct interface_manager_t {
+struct controller_t {
 
        /**
-        * @brief Create an iterator for all IKE_SAs.
+        * Create an iterator for all IKE_SAs.
         *
         * The iterator blocks the IKE_SA manager until it gets destroyed. Do
         * not call another interface/manager method while the iterator is alive.
         *
-        * @param this                  calling object
         * @return                              iterator, locks IKE_SA manager until destroyed
         */
-       iterator_t* (*create_ike_sa_iterator)(interface_manager_t *this);
+       iterator_t* (*create_ike_sa_iterator)(controller_t *this);
 
        /**
-        * @brief Initiate a CHILD_SA, and if required, an IKE_SA.
+        * Initiate a CHILD_SA, and if required, an IKE_SA.
         *
         * The inititate() function is synchronous and thus blocks until the
         * IKE_SA is established or failed. Because of this, the initiate() function
         * contains a thread cancellation point.
         *
-        * @param this                  calling object
         * @param peer_cfg              peer_cfg to use for IKE_SA setup
         * @param child_cfg             child_cfg to set up CHILD_SA from
         * @param cb                    logging callback
@@ -112,18 +89,17 @@ struct interface_manager_t {
         *                                              - FAILED, if setup failed
         *                                              - NEED_MORE, if callback returned FALSE
         */
-       status_t (*initiate)(interface_manager_t *this,
+       status_t (*initiate)(controller_t *this,
                                                 peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
-                                                interface_manager_cb_t callback, void *param);
+                                                controller_cb_t callback, void *param);
 
        /**
-        * @brief Terminate an IKE_SA and all of its CHILD_SAs.
+        * Terminate an IKE_SA and all of its CHILD_SAs.
         *
         * The terminate() function is synchronous and thus blocks until the
         * IKE_SA is properly deleted, or the delete timed out. 
         * The terminate() function contains a thread cancellation point.
         *
-        * @param this                  calling object
         * @param unique_id             unique id of the IKE_SA to terminate.
         * @param cb                    logging callback
         * @param param                 parameter to include in each call of cb
@@ -132,13 +108,12 @@ struct interface_manager_t {
         *                                              - NOT_FOUND, if no such CHILD_SA found
         *                                              - NEED_MORE, if callback returned FALSE
         */
-       status_t (*terminate_ike)(interface_manager_t *this, u_int32_t unique_id, 
-                                                         interface_manager_cb_t callback, void *param);
+       status_t (*terminate_ike)(controller_t *this, u_int32_t unique_id, 
+                                                         controller_cb_t callback, void *param);
        
        /**
-        * @brief Terminate a CHILD_SA.
+        * Terminate a CHILD_SA.
         *
-        * @param this                  calling object
         * @param reqid                 reqid of the CHILD_SA to terminate
         * @param cb                    logging callback
         * @param param                 parameter to include in each call of cb
@@ -147,13 +122,12 @@ struct interface_manager_t {
         *                                              - NOT_FOUND, if no such CHILD_SA found
         *                                              - NEED_MORE, if callback returned FALSE
         */
-       status_t (*terminate_child)(interface_manager_t *this, u_int32_t reqid, 
-                                                               interface_manager_cb_t callback, void *param);
+       status_t (*terminate_child)(controller_t *this, u_int32_t reqid, 
+                                                               controller_cb_t callback, void *param);
        
        /**
-        * @brief Route a CHILD_SA (install triggering policies).
+        * Route a CHILD_SA (install triggering policies).
         *
-        * @param this                  calling object
         * @param peer_cfg              peer_cfg to use for IKE_SA setup, if triggered
         * @param child_cfg             child_cfg to route
         * @param cb                    logging callback
@@ -163,16 +137,15 @@ struct interface_manager_t {
         *                                              - FAILED, if routing failed
         *                                              - NEED_MORE, if callback returned FALSE
         */
-       status_t (*route)(interface_manager_t *this,
+       status_t (*route)(controller_t *this,
                                          peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
-                                         interface_manager_cb_t callback, void *param);
+                                         controller_cb_t callback, void *param);
        
        /**
-        * @brief Unroute a routed CHILD_SA (uninstall triggering policies).
+        * Unroute a routed CHILD_SA (uninstall triggering policies).
         *
         * Only the route is removed, not the CHILD_SAs the route triggered.
         *
-        * @param this                  calling object
         * @param reqid                 reqid of the CHILD_SA to unroute
         * @param cb                    logging callback
         * @param param                 parameter to include in each call of cb
@@ -181,26 +154,21 @@ struct interface_manager_t {
         *                                              - NOT_FOUND, if no such CHILD_SA routed
         *                                              - NEED_MORE, if callback returned FALSE
         */
-       status_t (*unroute)(interface_manager_t *this, u_int32_t reqid, 
-                                               interface_manager_cb_t callback, void *param);
+       status_t (*unroute)(controller_t *this, u_int32_t reqid, 
+                                               controller_cb_t callback, void *param);
        
        /**
-        * @brief Destroy a interface_manager_t instance.
-        * 
-        * @param this          interface_manager_t objec to destroy
+        * Destroy a controller_t instance.
         */
-       void (*destroy) (interface_manager_t *this);
+       void (*destroy) (controller_t *this);
 };
 
 
 /**
- * @brief Creates a interface_manager instance and loads all interface modules.
- * 
- * @return                     interface_manager_t object
+ * Creates a controller instance.
  * 
- * @ingroup control
+ * @return                     controller_t object
  */
-interface_manager_t *interface_manager_create(void);
-
-#endif /* INTERFACE_MANAGER_H_ */
+controller_t *controller_create(void);
 
+#endif /* CONTROLLER_H_ @} */
diff --git a/src/charon/control/interfaces/interface.h b/src/charon/control/interfaces/interface.h
deleted file mode 100644 (file)
index 955f4a4..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file interface.h
- *
- * @brief Interface of interface_t.
- *
- */
-
-/*
- * 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.
- */
-
-#ifndef INTERFACE_H_
-#define INTERFACE_H_
-
-typedef struct interface_t interface_t;
-
-/**
- * @brief Interface for a controller.
- *
- * An interface controls the daemon by calling functions on the
- * interface_manager. All interfaces are manager by the interface_manager
- * in a generic way, so they need their own class.
- * 
- * @b Constructors:
- * - interface_create() of one of the modules
- * 
- * @ingroup interfaces
- */
-struct interface_t {
-       
-       /**
-        * @brief Destroy all interfaces
-        * 
-        * @param this          stroke_t objec to destroy
-        */
-       void (*destroy) (interface_t *this);
-};
-
-
-/**
- * Constructor in a control interface module to create the interface.
- *
- * @ingroup interfaces
- */
-typedef interface_t*(*interface_constructor_t)(void);
-
-#endif /* INTERFACE_H_ */
-
diff --git a/src/charon/control/interfaces/stroke_interface.c b/src/charon/control/interfaces/stroke_interface.c
deleted file mode 100755 (executable)
index 3b4b246..0000000
+++ /dev/null
@@ -1,1818 +0,0 @@
-/**
- * @file stroke_interface.c
- * 
- * @brief Implementation of stroke_interface_t.
- * 
- */
-
-/*
- * Copyright (C) 2007 Tobias Brunner
- * Copyright (C) 2006-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 <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include "stroke_interface.h"
-
-#include <library.h>
-#include <stroke.h>
-#include <daemon.h>
-#include <crypto/x509.h>
-#include <crypto/ietf_attr_list.h>
-#include <crypto/ac.h>
-#include <crypto/ca.h>
-#include <crypto/crl.h>
-#include <control/interface_manager.h>
-#include <control/interfaces/interface.h>
-#include <utils/leak_detective.h>
-#include <processing/jobs/callback_job.h>
-
-#define IKE_PORT       500
-#define PATH_BUF       256
-#define STROKE_THREADS 3
-
-typedef struct private_stroke_interface_t private_stroke_interface_t;
-
-/**
- * Private data of an stroke_interfacet object.
- */
-struct private_stroke_interface_t {
-
-       /**
-        * Public part of stroke_interfacet object.
-        */
-       stroke_interface_t public;
-               
-       /**
-        * Unix socket to listen for strokes
-        */
-       int socket;
-       
-       /**
-        * job accepting stroke messages
-        */
-       callback_job_t *job;
-};
-
-typedef struct stroke_log_info_t stroke_log_info_t;
-
-/**
- * helper struct to say what and where to log when using controller callback
- */
-struct stroke_log_info_t {
-
-       /**
-        * level to log up to
-        */
-       level_t level;
-       
-       /**
-        * where to write log
-        */
-       FILE* out;
-};
-
-/**
- * Helper function which corrects the string pointers
- * in a stroke_msg_t. Strings in a stroke_msg sent over "wire"
- * contains RELATIVE addresses (relative to the beginning of the
- * stroke_msg). They must be corrected if they reach our address
- * space...
- */
-static void pop_string(stroke_msg_t *msg, char **string)
-{
-       if (*string == NULL)
-               return;
-
-       /* check for sanity of string pointer and string */
-       if (string < (char**)msg
-       ||      string > (char**)msg + sizeof(stroke_msg_t)
-       || (unsigned long)*string < (unsigned long)((char*)msg->buffer - (char*)msg)
-       || (unsigned long)*string > msg->length)
-       {
-               *string = "(invalid pointer in stroke msg)";
-       }
-       else
-       {
-               *string = (char*)msg + (unsigned long)*string;
-       }
-}
-
-/**
- * Load end entitity certificate
- */
-static x509_t* load_end_certificate(const char *filename, identification_t **idp)
-{
-       char path[PATH_BUF];
-       x509_t *cert;
-
-       if (*filename == '/')
-       {
-               /* absolute path name */
-               snprintf(path, sizeof(path), "%s", filename);
-       }
-       else
-       {
-               /* relative path name */
-               snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
-       }
-
-       cert = x509_create_from_file(path, "end entity");
-
-       if (cert)
-       {
-               identification_t *id = *idp;
-               identification_t *subject = cert->get_subject(cert);
-
-               err_t ugh = cert->is_valid(cert, NULL);
-
-               if (ugh != NULL)        
-               {
-                       DBG1(DBG_CFG, "warning: certificate %s", ugh);
-               }
-               if (!id->equals(id, subject) && !cert->equals_subjectAltName(cert, id))
-               {
-                       id->destroy(id);
-                       id = subject;
-                       *idp = id->clone(id);
-               }
-               return charon->credentials->add_end_certificate(charon->credentials, cert);
-       }
-       return NULL;
-}
-
-/**
- * Load ca certificate
- */
-static x509_t* load_ca_certificate(const char *filename)
-{
-       char path[PATH_BUF];
-       x509_t *cert;
-
-       if (*filename == '/')
-       {
-               /* absolute path name */
-               snprintf(path, sizeof(path), "%s", filename);
-       }
-       else
-       {
-               /* relative path name */
-               snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
-       }
-
-       cert = x509_create_from_file(path, "ca");
-
-       if (cert)
-       {
-               if (cert->is_ca(cert))
-               {
-                       return charon->credentials->add_auth_certificate(charon->credentials, cert, AUTH_CA);
-               }
-               else
-               {
-                       DBG1(DBG_CFG, "  CA basic constraints flag not set, cert discarded");
-                       cert->destroy(cert);
-               }
-       }
-       return NULL;
-}
-
-/**
- * Pop the strings of a stroke_end_t struct and log them for debugging purposes
- */
-static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
-{
-       pop_string(msg, &end->address);
-       pop_string(msg, &end->subnet);
-       pop_string(msg, &end->sourceip);
-       pop_string(msg, &end->id);
-       pop_string(msg, &end->cert);
-       pop_string(msg, &end->ca);
-       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->subnet);
-       DBG2(DBG_CFG, "  %ssourceip=%s", label, end->sourceip);
-       DBG2(DBG_CFG, "  %sid=%s", label, end->id);
-       DBG2(DBG_CFG, "  %scert=%s", label, end->cert);
-       DBG2(DBG_CFG, "  %sca=%s", label, end->ca);
-       DBG2(DBG_CFG, "  %sgroups=%s", label, end->groups);
-       DBG2(DBG_CFG, "  %supdown=%s", label, end->updown);
-}
-
-/**
- * Add a connection to the configuration list
- */
-static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
-{
-       ike_cfg_t *ike_cfg;
-       peer_cfg_t *peer_cfg;
-       peer_cfg_t *mediated_by_cfg = NULL;
-       child_cfg_t *child_cfg;
-       identification_t *my_id, *other_id;
-       identification_t *my_ca = NULL;
-       identification_t *other_ca = NULL;
-       identification_t *peer_id = NULL;
-       bool my_ca_same = FALSE;
-       bool other_ca_same =FALSE;
-       host_t *my_host, *other_host, *my_subnet, *other_subnet;
-       host_t *my_vip = NULL, *other_vip = NULL;
-       linked_list_t *other_groups = linked_list_create();
-       proposal_t *proposal;
-       traffic_selector_t *my_ts, *other_ts;
-       char *interface;
-       bool use_existing = FALSE;
-       iterator_t *iterator;
-       u_int32_t vendor;
-       
-       pop_string(msg, &msg->add_conn.name);
-       DBG1(DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);
-       DBG2(DBG_CFG, "conn %s", msg->add_conn.name);
-       pop_end(msg, "left", &msg->add_conn.me);
-       pop_end(msg, "right", &msg->add_conn.other);
-       pop_string(msg, &msg->add_conn.algorithms.ike);
-       pop_string(msg, &msg->add_conn.algorithms.esp);
-       DBG2(DBG_CFG, "  ike=%s", msg->add_conn.algorithms.ike);
-       DBG2(DBG_CFG, "  esp=%s", msg->add_conn.algorithms.esp);
-       pop_string(msg, &msg->add_conn.p2p.mediated_by);
-       pop_string(msg, &msg->add_conn.p2p.peerid);
-       DBG2(DBG_CFG, "  p2p_mediation=%s", msg->add_conn.p2p.mediation ? "yes" : "no");
-       DBG2(DBG_CFG, "  p2p_mediated_by=%s", msg->add_conn.p2p.mediated_by);
-       DBG2(DBG_CFG, "  p2p_peerid=%s", msg->add_conn.p2p.peerid);
-
-       my_host = msg->add_conn.me.address ?
-                         host_create_from_string(msg->add_conn.me.address, IKE_PORT) : NULL;
-       if (my_host == NULL)
-       {
-               DBG1(DBG_CFG, "invalid host: %s\n", msg->add_conn.me.address);
-               return;
-       }
-
-       other_host = msg->add_conn.other.address ?
-                       host_create_from_string(msg->add_conn.other.address, IKE_PORT) : NULL;
-       if (other_host == NULL)
-       {
-               DBG1(DBG_CFG, "invalid host: %s\n", msg->add_conn.other.address);
-               my_host->destroy(my_host);
-               return;
-       }
-       
-       interface = charon->kernel_interface->get_interface(charon->kernel_interface, 
-                                                                                                               other_host);
-       if (interface)
-       {
-               stroke_end_t tmp_end;
-               host_t *tmp_host;
-
-               DBG2(DBG_CFG, "left is other host, swapping ends\n");
-
-               tmp_host = my_host;
-               my_host = other_host;
-               other_host = tmp_host;
-
-               tmp_end = msg->add_conn.me;
-               msg->add_conn.me = msg->add_conn.other;
-               msg->add_conn.other = tmp_end;
-               free(interface);
-       }
-       else
-       {
-               interface = charon->kernel_interface->get_interface(
-                                                                                       charon->kernel_interface, my_host);
-               if (!interface)
-               {
-                       DBG1(DBG_CFG, "left nor right host is our side, assuming left=local");
-               }
-               else
-               {
-                       free(interface);
-               }
-       }
-
-       my_id = identification_create_from_string(msg->add_conn.me.id ?
-                                               msg->add_conn.me.id : msg->add_conn.me.address);
-       if (my_id == NULL)
-       {
-               DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.me.id);
-               goto destroy_hosts;
-       }
-
-       other_id = identification_create_from_string(msg->add_conn.other.id ?
-                                               msg->add_conn.other.id : msg->add_conn.other.address);
-       if (other_id == NULL)
-       {
-               DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.other.id);
-               my_id->destroy(my_id);
-               goto destroy_hosts;
-       }
-       
-#ifdef P2P
-       if (msg->add_conn.p2p.mediation && msg->add_conn.p2p.mediated_by)
-       {
-               DBG1(DBG_CFG, "a mediation connection cannot be a"
-                               " mediated connection at the same time, aborting");
-               goto destroy_ids;
-       }
-       
-       if (msg->add_conn.p2p.mediated_by)
-       {
-               mediated_by_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, msg->add_conn.p2p.mediated_by);
-               if (!mediated_by_cfg)
-               {
-                       DBG1(DBG_CFG, "mediation connection '%s' not found, aborting",
-                                       msg->add_conn.p2p.mediated_by);
-                       goto destroy_ids;
-               }
-               
-               if (!mediated_by_cfg->is_mediation(mediated_by_cfg))
-               {
-                       DBG1(DBG_CFG, "connection '%s' as referred to by '%s' is"
-                                       "no mediation connection, aborting", 
-                                       msg->add_conn.p2p.mediated_by, msg->add_conn.name);
-                       goto destroy_ids;
-               }
-       }
-       
-       if (msg->add_conn.p2p.peerid)
-       {
-               peer_id = identification_create_from_string(msg->add_conn.p2p.peerid);
-               if (!peer_id)
-               {
-                       DBG1(DBG_CFG, "invalid peer ID: %s\n", msg->add_conn.p2p.peerid);
-                       goto destroy_ids;
-               }
-       }
-       else
-       {
-               /* no peer ID supplied, assume right ID */
-               peer_id = other_id->clone(other_id);
-       }
-#endif /* P2P */
-       
-       my_subnet = host_create_from_string(msg->add_conn.me.subnet ?
-                                       msg->add_conn.me.subnet : msg->add_conn.me.address, IKE_PORT);
-       if (my_subnet == NULL)
-       {
-               DBG1(DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
-               goto destroy_ids;
-       }
-       
-       other_subnet = host_create_from_string(msg->add_conn.other.subnet ?
-                                       msg->add_conn.other.subnet : msg->add_conn.other.address, IKE_PORT);
-       if (other_subnet == NULL)
-       {
-               DBG1(DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
-               my_subnet->destroy(my_subnet);
-               goto destroy_ids;
-       }
-       
-       if (msg->add_conn.me.virtual_ip && msg->add_conn.me.sourceip)
-       {
-               my_vip = host_create_from_string(msg->add_conn.me.sourceip, 0);
-       }
-       if (msg->add_conn.other.virtual_ip && msg->add_conn.other.sourceip)
-       {
-               other_vip = host_create_from_string(msg->add_conn.other.sourceip, 0);
-       }
-       
-       if (msg->add_conn.me.tohost)
-       {
-               my_ts = traffic_selector_create_dynamic(msg->add_conn.me.protocol,
-                                       my_host->get_family(my_host) == AF_INET ?
-                                               TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE,
-                                       msg->add_conn.me.port ? msg->add_conn.me.port : 0,
-                                       msg->add_conn.me.port ? msg->add_conn.me.port : 65535);
-       }
-       else
-       {
-               my_ts = traffic_selector_create_from_subnet(my_subnet,
-                               msg->add_conn.me.subnet ?  msg->add_conn.me.subnet_mask : 0,
-                               msg->add_conn.me.protocol, msg->add_conn.me.port);
-       }
-       my_subnet->destroy(my_subnet);
-       
-       if (msg->add_conn.other.tohost)
-       {
-               other_ts = traffic_selector_create_dynamic(msg->add_conn.other.protocol,
-                                       other_host->get_family(other_host) == AF_INET ?
-                                               TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE,
-                                       msg->add_conn.other.port ? msg->add_conn.other.port : 0,
-                                       msg->add_conn.other.port ? msg->add_conn.other.port : 65535);
-       }
-       else
-       {
-               other_ts = traffic_selector_create_from_subnet(other_subnet, 
-                               msg->add_conn.other.subnet ?  msg->add_conn.other.subnet_mask : 0,
-                               msg->add_conn.other.protocol, msg->add_conn.other.port);
-       }
-       other_subnet->destroy(other_subnet);
-
-       if (msg->add_conn.me.ca)
-       {
-               if (streq(msg->add_conn.me.ca, "%same"))
-               {
-                       my_ca_same = TRUE;
-               }
-               else
-               {
-                       my_ca = identification_create_from_string(msg->add_conn.me.ca);
-               }
-       }
-       if (msg->add_conn.other.ca)
-       {
-               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 (msg->add_conn.me.cert)
-       {
-               x509_t *cert = load_end_certificate(msg->add_conn.me.cert, &my_id);
-
-               if (cert)
-               {
-                       ca_info_t *ca_info;
-
-                       if (cert->is_self_signed(cert))
-                       {
-                               /* a self-signed certificate is its own ca */
-                               ca_info = ca_info_create(NULL, cert);
-                               ca_info = charon->credentials->add_ca_info(charon->credentials, ca_info);
-                               cert->set_ca_info(cert, ca_info);
-                       }
-                       else
-                       {
-                               /* get_issuer() automatically sets cert->ca_info */
-                               ca_info = charon->credentials->get_issuer(charon->credentials, cert);
-                       }
-                       if (my_ca == NULL && !my_ca_same)
-                       {
-                               identification_t *issuer = cert->get_issuer(cert);
-
-                               my_ca = issuer->clone(issuer);
-                       }
-               }
-       }
-       if (msg->add_conn.other.cert)
-       {
-               x509_t *cert = load_end_certificate(msg->add_conn.other.cert, &other_id);
-
-               if (cert)
-               {
-                       ca_info_t *ca_info;
-
-                       if (cert->is_self_signed(cert))
-                       {
-                               /* a self-signed certificate is its own ca */
-                               ca_info = ca_info_create(NULL, cert);
-                               ca_info = charon->credentials->add_ca_info(charon->credentials, ca_info);
-                               cert->set_ca_info(cert, ca_info);
-                       }
-                       else
-                       {
-                               /* get_issuer() automatically sets cert->ca_info */
-                               ca_info = charon->credentials->get_issuer(charon->credentials, cert);
-                       }
-                       if (other_ca == NULL && !other_ca_same)
-                       {
-                               identification_t *issuer = cert->get_issuer(cert);
-
-                               other_ca = issuer->clone(issuer);
-                       }
-               }
-       }
-       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 (my_ca == NULL)
-       {
-               my_ca = identification_create_from_string("%any");
-       }
-       if (other_ca == NULL)
-       {
-               other_ca = identification_create_from_string("%any");
-       }
-       DBG2(DBG_CFG, "  my ca:   '%D'", my_ca);
-       DBG2(DBG_CFG, "  other ca:'%D'", other_ca);
-
-       if (msg->add_conn.other.groups)
-       {
-               ietfAttr_list_create_from_string(msg->add_conn.other.groups, other_groups);
-       }
-
-       /* have a look for an (almost) identical peer config to reuse */
-       iterator = charon->backends->create_iterator(charon->backends);
-       while (iterator->iterate(iterator, (void**)&peer_cfg))
-       {
-               host_t *my_vip_conf, *other_vip_conf;
-               bool my_vip_equals = FALSE, other_vip_equals = FALSE;
-               
-               my_vip_conf = peer_cfg->get_my_virtual_ip(peer_cfg);
-               if ((my_vip && my_vip_conf && my_vip->equals(my_vip, my_vip_conf)) ||
-                       (!my_vip_conf && !my_vip))
-               {
-                       my_vip_equals = TRUE;
-               }
-               DESTROY_IF(my_vip_conf);
-               other_vip_conf = peer_cfg->get_other_virtual_ip(peer_cfg, NULL);
-               if ((other_vip && other_vip_conf && other_vip->equals(other_vip, other_vip_conf)) ||
-                       (!other_vip_conf && !other_vip))
-               {
-                       other_vip_equals = TRUE;
-               }
-               DESTROY_IF(other_vip_conf);
-               
-               ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
-               if (my_id->equals(my_id, peer_cfg->get_my_id(peer_cfg))
-               &&      other_id->equals(other_id, peer_cfg->get_other_id(peer_cfg))
-               &&      my_host->equals(my_host, ike_cfg->get_my_host(ike_cfg))
-               &&      other_host->equals(other_host, ike_cfg->get_other_host(ike_cfg))
-               &&      other_ca->equals(other_ca, peer_cfg->get_other_ca(peer_cfg))
-               &&  ietfAttr_list_equals(other_groups, peer_cfg->get_groups(peer_cfg))
-               &&      peer_cfg->get_ike_version(peer_cfg) == (msg->add_conn.ikev2 ? 2 : 1)
-               &&      peer_cfg->get_auth_method(peer_cfg) == msg->add_conn.auth_method
-               &&      peer_cfg->get_eap_type(peer_cfg, &vendor) == msg->add_conn.eap_type
-               &&      vendor == msg->add_conn.eap_vendor
-               &&  my_vip_equals && other_vip_equals)
-               {
-                       DBG1(DBG_CFG, "reusing existing configuration '%s'",
-                                peer_cfg->get_name(peer_cfg));
-                       use_existing = TRUE;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-
-       if (use_existing)
-       {
-               DESTROY_IF(my_vip);
-               DESTROY_IF(other_vip);
-               my_host->destroy(my_host);
-               my_id->destroy(my_id);
-               my_ca->destroy(my_ca);
-               other_host->destroy(other_host);
-               other_id->destroy(other_id);
-               other_ca->destroy(other_ca);
-               DESTROY_IF(peer_id);
-               DESTROY_IF(mediated_by_cfg);
-               ietfAttr_list_destroy(other_groups);
-       }
-       else
-       {
-               ike_cfg = ike_cfg_create(msg->add_conn.other.sendcert != CERT_NEVER_SEND,
-                                                                msg->add_conn.force_encap, my_host, other_host);
-
-               if (msg->add_conn.algorithms.ike)
-               {
-                       char *proposal_string;
-                       char *strict = msg->add_conn.algorithms.ike + strlen(msg->add_conn.algorithms.ike) - 1;
-
-                       if (*strict == '!')
-                               *strict = '\0';
-                       else
-                               strict = NULL;
-
-                       while ((proposal_string = strsep(&msg->add_conn.algorithms.ike, ",")))
-                       {
-                               proposal = proposal_create_from_string(PROTO_IKE, proposal_string);
-                               if (proposal == NULL)
-                               {
-                                       DBG1(DBG_CFG, "invalid IKE proposal string: %s", proposal_string);
-                                       my_id->destroy(my_id);
-                                       other_id->destroy(other_id);
-                                       my_ts->destroy(my_ts);
-                                       other_ts->destroy(other_ts);
-                                       my_ca->destroy(my_ca);
-                                       other_ca->destroy(other_ca);
-                                       ike_cfg->destroy(ike_cfg);
-                                       return;
-                               }
-                               ike_cfg->add_proposal(ike_cfg, proposal);
-                       }
-                       if (!strict)
-                       {
-                               proposal = proposal_create_default(PROTO_IKE);
-                               ike_cfg->add_proposal(ike_cfg, proposal);
-                       }
-               }
-               else
-               {
-                       proposal = proposal_create_default(PROTO_IKE);
-                       ike_cfg->add_proposal(ike_cfg, proposal);
-               }
-               
-               u_int32_t rekey = 0, reauth = 0, over, jitter;
-               
-               jitter = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;
-               over = msg->add_conn.rekey.margin;
-               if (msg->add_conn.rekey.reauth)
-               {
-                       reauth = msg->add_conn.rekey.ike_lifetime - over;
-               }
-               else
-               {
-                       rekey = msg->add_conn.rekey.ike_lifetime - over;
-               }
-               
-               peer_cfg = peer_cfg_create(msg->add_conn.name, msg->add_conn.ikev2 ? 2 : 1,
-                                       ike_cfg, my_id, other_id, my_ca, other_ca, other_groups,
-                                       msg->add_conn.me.sendcert, msg->add_conn.auth_method,
-                                       msg->add_conn.eap_type, msg->add_conn.eap_vendor,
-                                       msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
-                                       msg->add_conn.mobike,
-                                       msg->add_conn.dpd.delay, msg->add_conn.dpd.action, my_vip, other_vip,
-                                       msg->add_conn.p2p.mediation, mediated_by_cfg, peer_id);
-       }
-       
-       child_cfg = child_cfg_create(
-                               msg->add_conn.name, msg->add_conn.rekey.ipsec_lifetime,
-                               msg->add_conn.rekey.ipsec_lifetime - msg->add_conn.rekey.margin,
-                               msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100, 
-                               msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
-                               msg->add_conn.mode);
-       
-       peer_cfg->add_child_cfg(peer_cfg, child_cfg);
-       
-       child_cfg->add_traffic_selector(child_cfg, TRUE, my_ts);
-       child_cfg->add_traffic_selector(child_cfg, FALSE, other_ts);
-       
-       if (msg->add_conn.algorithms.esp)
-       {
-               char *proposal_string;
-               char *strict = msg->add_conn.algorithms.esp + strlen(msg->add_conn.algorithms.esp) - 1;
-
-               if (*strict == '!')
-                       *strict = '\0';
-               else
-                       strict = NULL;
-               
-               while ((proposal_string = strsep(&msg->add_conn.algorithms.esp, ",")))
-               {
-                       proposal = proposal_create_from_string(PROTO_ESP, proposal_string);
-                       if (proposal == NULL)
-                       {
-                               DBG1(DBG_CFG, "invalid ESP proposal string: %s", proposal_string);
-                               peer_cfg->destroy(peer_cfg);
-                               return;
-                       }
-                       child_cfg->add_proposal(child_cfg, proposal);
-               }
-               if (!strict)
-               {
-                       proposal = proposal_create_default(PROTO_ESP);
-                       child_cfg->add_proposal(child_cfg, proposal);
-               }
-       }
-       else
-       {
-               proposal = proposal_create_default(PROTO_ESP);
-               child_cfg->add_proposal(child_cfg, proposal);
-       }
-       
-       if (!use_existing)
-       {
-               /* add config to backend */
-               charon->backends->add_peer_cfg(charon->backends, peer_cfg);
-               DBG1(DBG_CFG, "added configuration '%s': %H[%D]...%H[%D]",
-                        msg->add_conn.name, my_host, my_id, other_host, other_id);
-       }
-       return;
-
-       /* mopping up after parsing errors */
-
-destroy_ids:
-       my_id->destroy(my_id);
-       other_id->destroy(other_id);
-       DESTROY_IF(mediated_by_cfg);
-       DESTROY_IF(peer_id);
-
-destroy_hosts:
-       my_host->destroy(my_host);
-       other_host->destroy(other_host);
-}
-
-/**
- * Delete a connection from the list
- */
-static void stroke_del_conn(stroke_msg_t *msg, FILE *out)
-{
-       iterator_t *peer_iter, *child_iter;
-       peer_cfg_t *peer;
-       child_cfg_t *child;
-       
-       pop_string(msg, &(msg->del_conn.name));
-       DBG1(DBG_CFG, "received stroke: delete connection '%s'", msg->del_conn.name);
-       
-       peer_iter = charon->backends->create_iterator(charon->backends);
-       while (peer_iter->iterate(peer_iter, (void**)&peer))
-       {
-               /* remove peer config with such a name */
-               if (streq(peer->get_name(peer), msg->del_conn.name))
-               {
-                       peer_iter->remove(peer_iter);
-                       peer->destroy(peer);
-                       continue;
-               }
-               /* remove any child with such a name */
-               child_iter = peer->create_child_cfg_iterator(peer);
-               while (child_iter->iterate(child_iter, (void**)&child))
-               {
-                       if (streq(child->get_name(child), msg->del_conn.name))
-                       {
-                               child_iter->remove(child_iter);
-                               child->destroy(child);
-                       }
-               }
-               child_iter->destroy(child_iter);
-       }
-       peer_iter->destroy(peer_iter);
-       
-       fprintf(out, "deleted connection '%s'\n", msg->del_conn.name);
-}
-
-/**
- * get the child_cfg with the same name as the peer cfg
- */
-static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
-{
-       child_cfg_t *current, *found = NULL;
-       iterator_t *iterator;
-       
-       iterator = peer_cfg->create_child_cfg_iterator(peer_cfg);
-       while (iterator->iterate(iterator, (void**)&current))
-       {
-               if (streq(current->get_name(current), name))
-               {
-                       found = current;
-                       found->get_ref(found);
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       return found;
-}
-
-/**
- * logging to the stroke interface
- */
-static bool stroke_log(stroke_log_info_t *info, signal_t signal, level_t level,
-                                          ike_sa_t *ike_sa, char *format, va_list args)
-{
-       if (level <= info->level)
-       {
-               if (vfprintf(info->out, format, args) < 0 ||
-                       fprintf(info->out, "\n") < 0 ||
-                       fflush(info->out) != 0)
-               {
-                       return FALSE;
-               }
-       }
-       return TRUE;
-}
-
-/**
- * initiate a connection by name
- */
-static void stroke_initiate(stroke_msg_t *msg, FILE *out)
-{
-       peer_cfg_t *peer_cfg;
-       child_cfg_t *child_cfg;
-       stroke_log_info_t info;
-       
-       pop_string(msg, &(msg->initiate.name));
-       DBG1(DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name);
-       
-       peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
-                                                                                                         msg->initiate.name);
-       if (peer_cfg == NULL)
-       {
-               fprintf(out, "no config named '%s'\n", msg->initiate.name);
-               return;
-       }
-       if (peer_cfg->get_ike_version(peer_cfg) != 2)
-       {
-               DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
-                        peer_cfg->get_ike_version(peer_cfg));
-               peer_cfg->destroy(peer_cfg);
-               return;
-       }
-       
-       child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
-       if (child_cfg == NULL)
-       {
-               fprintf(out, "no child config named '%s'\n", msg->initiate.name);
-               peer_cfg->destroy(peer_cfg);
-               return;
-       }
-       
-       if (msg->output_verbosity < 0)
-       {
-               charon->interfaces->initiate(charon->interfaces, peer_cfg, child_cfg,
-                                                                        NULL, NULL);
-       }
-       else
-       {
-               info.out = out;
-               info.level = msg->output_verbosity;
-               charon->interfaces->initiate(charon->interfaces, peer_cfg, child_cfg,
-                                                                        (interface_manager_cb_t)stroke_log, &info);
-       }
-}
-
-/**
- * route a policy (install SPD entries)
- */
-static void stroke_route(stroke_msg_t *msg, FILE *out)
-{
-       peer_cfg_t *peer_cfg;
-       child_cfg_t *child_cfg;
-       stroke_log_info_t info;
-       
-       pop_string(msg, &(msg->route.name));
-       DBG1(DBG_CFG, "received stroke: route '%s'", msg->route.name);
-       
-       peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
-                                                                                                         msg->route.name);
-       if (peer_cfg == NULL)
-       {
-               fprintf(out, "no config named '%s'\n", msg->route.name);
-               return;
-       }
-       if (peer_cfg->get_ike_version(peer_cfg) != 2)
-       {
-               peer_cfg->destroy(peer_cfg);
-               return;
-       }
-       
-       child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
-       if (child_cfg == NULL)
-       {
-               fprintf(out, "no child config named '%s'\n", msg->route.name);
-               peer_cfg->destroy(peer_cfg);
-               return;
-       }
-       
-       info.out = out;
-       info.level = msg->output_verbosity;
-       charon->interfaces->route(charon->interfaces, peer_cfg, child_cfg,
-                                                         (interface_manager_cb_t)stroke_log, &info);
-       peer_cfg->destroy(peer_cfg);
-       child_cfg->destroy(child_cfg);
-}
-
-/**
- * unroute a policy
- */
-static void stroke_unroute(stroke_msg_t *msg, FILE *out)
-{
-       char *name;
-       ike_sa_t *ike_sa;
-       iterator_t *iterator;
-       stroke_log_info_t info;
-       
-       pop_string(msg, &(msg->terminate.name));
-       name = msg->terminate.name;
-       
-       info.out = out;
-       info.level = msg->output_verbosity;
-       
-       iterator = charon->interfaces->create_ike_sa_iterator(charon->interfaces);
-       while (iterator->iterate(iterator, (void**)&ike_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 (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);
-                               iterator->destroy(iterator);
-                               charon->interfaces->unroute(charon->interfaces, id,
-                                                               (interface_manager_cb_t)stroke_log, &info);
-                               return;
-                       }
-               }
-               children->destroy(children);
-       }
-       iterator->destroy(iterator);
-       DBG1(DBG_CFG, "no such SA found");
-}
-
-/**
- * terminate a connection by name
- */
-static void stroke_terminate(stroke_msg_t *msg, FILE *out)
-{
-       char *string, *pos = NULL, *name = NULL;
-       u_int32_t id = 0;
-       bool child;
-       int len;
-       ike_sa_t *ike_sa;
-       iterator_t *iterator;
-       stroke_log_info_t info;
-       
-       pop_string(msg, &(msg->terminate.name));
-       string = msg->terminate.name;
-       DBG1(DBG_CFG, "received stroke: terminate '%s'", string);
-       
-       len = strlen(string);
-       if (len < 1)
-       {
-               DBG1(DBG_CFG, "error parsing string");
-               return;
-       }
-       switch (string[len-1])
-       {
-               case '}':
-                       child = TRUE;
-                       pos = strchr(string, '{');
-                       break;
-               case ']':
-                       child = FALSE;
-                       pos = strchr(string, '[');
-                       break;
-               default:
-                       name = string;
-                       child = FALSE;
-                       break;
-       }
-       
-       if (name)
-       {
-               /* is a single name */
-       }
-       else if (pos == string + len - 2)
-       {       /* is name[] or name{} */
-               string[len-2] = '\0';
-               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;
-               }
-       }
-       
-       info.out = out;
-       info.level = msg->output_verbosity;
-       
-       iterator = charon->interfaces->create_ike_sa_iterator(charon->interfaces);
-       while (iterator->iterate(iterator, (void**)&ike_sa))
-       {
-               child_sa_t *child_sa;
-               iterator_t *children;
-               
-               if (child)
-               {
-                       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)))
-                               {
-                                       id = child_sa->get_reqid(child_sa);
-                                       children->destroy(children);
-                                       iterator->destroy(iterator);
-                                       
-                                       charon->interfaces->terminate_child(charon->interfaces, id,
-                                                                       (interface_manager_cb_t)stroke_log, &info);
-                                       return;
-                               }
-                       }
-                       children->destroy(children);
-               }
-               else if ((name && streq(name, ike_sa->get_name(ike_sa))) ||
-                                (id && id == ike_sa->get_unique_id(ike_sa)))
-               {
-                       id = ike_sa->get_unique_id(ike_sa);
-                       /* unlock manager first */
-                       iterator->destroy(iterator);
-                       
-                       charon->interfaces->terminate_ike(charon->interfaces, id,
-                                                                       (interface_manager_cb_t)stroke_log, &info);
-                       return;
-               }
-               
-       }
-       iterator->destroy(iterator);
-       DBG1(DBG_CFG, "no such SA found");
-}
-
-/**
- * Add a ca information record to the cainfo list
- */
-static void stroke_add_ca(stroke_msg_t *msg, FILE *out)
-{
-       x509_t *cacert;
-       ca_info_t *ca_info;
-
-       pop_string(msg, &msg->add_ca.name);
-       pop_string(msg, &msg->add_ca.cacert);
-       pop_string(msg, &msg->add_ca.crluri);
-       pop_string(msg, &msg->add_ca.crluri2);
-       pop_string(msg, &msg->add_ca.ocspuri);
-       pop_string(msg, &msg->add_ca.ocspuri2);
-       
-       DBG1(DBG_CFG, "received stroke: add ca '%s'", msg->add_ca.name);
-       
-       DBG2(DBG_CFG, "ca %s",        msg->add_ca.name);
-       DBG2(DBG_CFG, "  cacert=%s",  msg->add_ca.cacert);
-       DBG2(DBG_CFG, "  crluri=%s",  msg->add_ca.crluri);
-       DBG2(DBG_CFG, "  crluri2=%s", msg->add_ca.crluri2);
-       DBG2(DBG_CFG, "  ocspuri=%s", msg->add_ca.ocspuri);
-       DBG2(DBG_CFG, "  ocspuri2=%s", msg->add_ca.ocspuri2);
-
-       if (msg->add_ca.cacert == NULL)
-       {
-               DBG1(DBG_CFG, "missing cacert parameter\n");
-               return;
-       }
-
-       cacert = load_ca_certificate(msg->add_ca.cacert);
-
-       if (cacert == NULL)
-       {
-               return;
-       }
-       ca_info = ca_info_create(msg->add_ca.name, cacert);
-
-       if (msg->add_ca.crluri)
-       {
-               chunk_t uri = { msg->add_ca.crluri, strlen(msg->add_ca.crluri) };
-               
-               ca_info->add_crluri(ca_info, uri);
-       }
-       if (msg->add_ca.crluri2)
-       {
-               chunk_t uri = { msg->add_ca.crluri2, strlen(msg->add_ca.crluri2) };
-               
-               ca_info->add_crluri(ca_info, uri);
-       }
-       if (msg->add_ca.ocspuri)
-       {
-               chunk_t uri = { msg->add_ca.ocspuri, strlen(msg->add_ca.ocspuri) };
-               
-               ca_info->add_ocspuri(ca_info, uri);
-       }
-       if (msg->add_ca.ocspuri2)
-       {
-               chunk_t uri = { msg->add_ca.ocspuri2, strlen(msg->add_ca.ocspuri2) };
-               
-               ca_info->add_ocspuri(ca_info, uri);
-       }
-       charon->credentials->add_ca_info(charon->credentials, ca_info);
-       DBG1(DBG_CFG, "added ca '%s'", msg->add_ca.name);
-
-}
-
-/**
- * Delete a ca information record from the cainfo list
- */
-static void stroke_del_ca(stroke_msg_t *msg, FILE *out)
-{
-       status_t status;
-       
-       pop_string(msg, &(msg->del_ca.name));
-       DBG1(DBG_CFG, "received stroke: delete ca '%s'", msg->del_ca.name);
-       
-       status = charon->credentials->release_ca_info(charon->credentials,
-                                                                                                 msg->del_ca.name);
-
-       if (status == SUCCESS)
-       {
-               fprintf(out, "deleted ca '%s'\n", msg->del_ca.name);
-       }
-       else
-       {
-               fprintf(out, "no ca named '%s'\n", msg->del_ca.name);
-       }
-}
-
-/**
- * log an IKE_SA to out
- */
-static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
-{
-       ike_sa_id_t *id = ike_sa->get_id(ike_sa);
-       u_int32_t rekey, reauth;
-
-       fprintf(out, "%12s[%d]: %N, %H[%D]...%H[%D]\n",
-                       ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
-                       ike_sa_state_names, ike_sa->get_state(ike_sa),
-                       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));
-       
-       if (all)
-       {
-               fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_r%s",
-                               ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
-                               id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "",
-                               id->get_responder_spi(id), id->is_initiator(id) ? "" : "*");
-       
-               rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY_TIME);
-               reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH_TIME);
-               if (rekey)
-               {
-                       fprintf(out, ", rekeying in %V", &rekey);
-               }
-               if (reauth)
-               {
-                       fprintf(out, ", reauthentication in %V", &reauth);
-               }
-               if (!rekey && !reauth)
-               {
-                       fprintf(out, ", rekeying disabled");
-               }
-               fprintf(out, "\n");
-       }
-}
-
-/**
- * log an CHILD_SA to out
- */
-static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
-{
-       u_int32_t rekey, now = time(NULL);
-       u_int32_t use_in, use_out, use_fwd;
-       encryption_algorithm_t encr_alg;
-       integrity_algorithm_t int_alg;
-       size_t encr_len, int_len;
-       mode_t mode;
-       
-       child_sa->get_stats(child_sa, &mode, &encr_alg, &encr_len,
-                                               &int_alg, &int_len, &rekey, &use_in, &use_out,
-                                               &use_fwd);
-       
-       fprintf(out, "%12s{%d}:  %N, %N", 
-                       child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
-                       child_sa_state_names, child_sa->get_state(child_sa),
-                       mode_names, mode);
-       
-       if (child_sa->get_state(child_sa) == CHILD_INSTALLED)
-       {
-               fprintf(out, ", %N SPIs: %.8x_i %.8x_o",
-                               protocol_id_names, child_sa->get_protocol(child_sa),
-                               htonl(child_sa->get_spi(child_sa, TRUE)),
-                               htonl(child_sa->get_spi(child_sa, FALSE)));
-               
-               if (all)
-               {
-                       fprintf(out, "\n%12s{%d}:  ", child_sa->get_name(child_sa), 
-                                       child_sa->get_reqid(child_sa));
-                       
-                       
-                       if (child_sa->get_protocol(child_sa) == PROTO_ESP)
-                       {
-                               fprintf(out, "%N", encryption_algorithm_names, encr_alg);
-                               
-                               if (encr_len)
-                               {
-                                       fprintf(out, "-%d", encr_len);
-                               }
-                               fprintf(out, "/");
-                       }
-                       
-                       fprintf(out, "%N", integrity_algorithm_names, int_alg);
-                       if (int_len)
-                       {
-                               fprintf(out, "-%d", int_len);
-                       }
-                       fprintf(out, ", rekeying ");
-                       
-                       if (rekey)
-                       {
-                               fprintf(out, "in %#V", &now, &rekey);
-                       }
-                       else
-                       {
-                               fprintf(out, "disabled");
-                       }
-                       
-                       fprintf(out, ", last use: ");
-                       use_in = max(use_in, use_fwd);
-                       if (use_in)
-                       {
-                               fprintf(out, "%ds_i ", now - use_in);
-                       }
-                       else
-                       {
-                               fprintf(out, "no_i ");
-                       }
-                       if (use_out)
-                       {
-                               fprintf(out, "%ds_o ", now - use_out);
-                       }
-                       else
-                       {
-                               fprintf(out, "no_o ");
-                       }
-               }
-       }
-       
-       fprintf(out, "\n%12s{%d}:   %#R=== %#R\n",
-                       child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
-                       child_sa->get_traffic_selectors(child_sa, TRUE),
-                       child_sa->get_traffic_selectors(child_sa, FALSE));
-}
-
-/**
- * show status of daemon
- */
-static void stroke_status(stroke_msg_t *msg, FILE *out, bool all)
-{
-       iterator_t *iterator, *children;
-       host_t *host;
-       peer_cfg_t *peer_cfg;
-       ike_cfg_t *ike_cfg;
-       child_cfg_t *child_cfg;
-       ike_sa_t *ike_sa;
-       char *name = NULL;
-       
-       if (msg->status.name)
-       {
-               pop_string(msg, &(msg->status.name));
-               name = msg->status.name;
-       }
-       
-       if (all)
-       {
-               leak_detective_status(out);
-       
-               fprintf(out, "Performance:\n");
-               fprintf(out, "  worker threads: %d idle of %d,",
-                               charon->processor->get_idle_threads(charon->processor),
-                               charon->processor->get_total_threads(charon->processor));
-               fprintf(out, " job queue load: %d,",
-                               charon->processor->get_job_load(charon->processor));
-               fprintf(out, " scheduled events: %d\n",
-                               charon->scheduler->get_job_load(charon->scheduler));
-               iterator = charon->kernel_interface->create_address_iterator(
-                                                                                                       charon->kernel_interface);
-               fprintf(out, "Listening IP addresses:\n");
-               while (iterator->iterate(iterator, (void**)&host))
-               {
-                       fprintf(out, "  %H\n", host);
-               }
-               iterator->destroy(iterator);
-       
-               fprintf(out, "Connections:\n");
-               iterator = charon->backends->create_iterator(charon->backends);
-               while (iterator->iterate(iterator, (void**)&peer_cfg))
-               {
-                       if (peer_cfg->get_ike_version(peer_cfg) != 2 ||
-                               (name && !streq(name, peer_cfg->get_name(peer_cfg))))
-                       {
-                               continue;
-                       }
-                       
-                       ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
-                       fprintf(out, "%12s:  %H[%D]...%H[%D]\n", peer_cfg->get_name(peer_cfg),
-                                       ike_cfg->get_my_host(ike_cfg), peer_cfg->get_my_id(peer_cfg),
-                                       ike_cfg->get_other_host(ike_cfg), peer_cfg->get_other_id(peer_cfg));
-                       {
-                               identification_t *my_ca = peer_cfg->get_my_ca(peer_cfg);
-                               identification_t *other_ca = peer_cfg->get_other_ca(peer_cfg);
-                               linked_list_t *groups = peer_cfg->get_groups(peer_cfg);
-
-                               if (my_ca->get_type(my_ca) != ID_ANY
-                               ||  other_ca->get_type(other_ca) != ID_ANY)
-                               {
-                                       fprintf(out, "%12s:    CAs: '%D'...'%D'\n", peer_cfg->get_name(peer_cfg),
-                                                       my_ca, other_ca);
-                               }
-                               if (groups->get_count(groups) > 0)
-                               {
-                                       fprintf(out, "%12s:    groups: ", peer_cfg->get_name(peer_cfg));
-                                       ietfAttr_list_list(groups, out);
-                                       fprintf(out, "\n");
-                               }
-                               
-                       }
-                       children = peer_cfg->create_child_cfg_iterator(peer_cfg);
-                       while (children->iterate(children, (void**)&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\n", 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));
-                       }
-                       children->destroy(children);
-               }
-               iterator->destroy(iterator);
-       }
-       
-       iterator = charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
-       if (all && iterator->get_count(iterator) > 0)
-       {
-               fprintf(out, "Security Associations:\n");
-       }
-       while (iterator->iterate(iterator, (void**)&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)))
-               {
-                       log_ike_sa(out, ike_sa, all);
-                       ike_printed = TRUE;
-               }
-
-               while (children->iterate(children, (void**)&child_sa))
-               {
-                       if (name == NULL || streq(name, child_sa->get_name(child_sa)))
-                       {
-                               if (!ike_printed)
-                               {
-                                       log_ike_sa(out, ike_sa, all);
-                                       ike_printed = TRUE;
-                               }
-                               log_child_sa(out, child_sa, all);
-                       }       
-               }
-               children->destroy(children);
-       }
-       iterator->destroy(iterator);
-}
-
-/**
- * list all authority certificates matching a specified flag 
- */
-static void list_auth_certificates(u_int flag, const char *label,
-                                                                  bool utc, FILE *out)
-{
-       bool first = TRUE;
-       x509_t *cert;
-       
-       iterator_t *iterator = charon->credentials->create_auth_cert_iterator(charon->credentials);
-
-       while (iterator->iterate(iterator, (void**)&cert))
-       {
-               if (cert->has_authority_flag(cert, flag))
-               {
-                       if (first)
-                       {
-                               fprintf(out, "\n");
-                               fprintf(out, "List of X.509 %s Certificates:\n", label);
-                               fprintf(out, "\n");
-                               first = FALSE;
-                       }
-                       cert->list(cert, out, utc);
-                       fprintf(out, "\n");
-               }
-       }
-       iterator->destroy(iterator);
-}
-
-/**
- * list various information
- */
-static void stroke_list(stroke_msg_t *msg, FILE *out)
-{
-       iterator_t *iterator;
-       
-       if (msg->list.flags & LIST_CERTS)
-       {
-               x509_t *cert;
-               
-               iterator = charon->credentials->create_cert_iterator(charon->credentials);
-               if (iterator->get_count(iterator))
-               {
-                       fprintf(out, "\n");
-                       fprintf(out, "List of X.509 End Entity Certificates:\n");
-                       fprintf(out, "\n");
-               }
-               while (iterator->iterate(iterator, (void**)&cert))
-               {
-                       cert->list(cert, out, msg->list.utc);
-                       if (charon->credentials->has_rsa_private_key(
-                                       charon->credentials, cert->get_public_key(cert)))
-                       {
-                               fprintf(out, ", has private key");
-                       }
-                       fprintf(out, "\n");
-                       
-               }
-               iterator->destroy(iterator);
-       }
-       if (msg->list.flags & LIST_CACERTS)
-       {
-               list_auth_certificates(AUTH_CA, "CA", msg->list.utc, out);
-       }
-       if (msg->list.flags & LIST_OCSPCERTS)
-       {
-               list_auth_certificates(AUTH_OCSP, "OCSP", msg->list.utc, out);
-       }
-       if (msg->list.flags & LIST_AACERTS)
-       {
-               list_auth_certificates(AUTH_AA, "AA", msg->list.utc, out);
-       }
-       if (msg->list.flags & LIST_ACERTS)
-       {
-               x509ac_t *cert;
-               
-               iterator = charon->credentials->create_acert_iterator(charon->credentials);
-               if (iterator->get_count(iterator))
-               {
-                       fprintf(out, "\n");
-                       fprintf(out, "List of X.509 Attribute Certificates:\n");
-                       fprintf(out, "\n");
-               }
-               while (iterator->iterate(iterator, (void**)&cert))
-               {
-                       cert->list(cert, out, msg->list.utc);
-               }
-               iterator->destroy(iterator);
-       }
-       if (msg->list.flags & LIST_CAINFOS)
-       {
-               ca_info_t *ca_info;
-               bool first = TRUE;
-
-               iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
-               while (iterator->iterate(iterator, (void**)&ca_info))
-               {
-                       if (ca_info->is_ca(ca_info))
-                       {
-                               if (first)
-                               {
-                                       fprintf(out, "\n");
-                                       fprintf(out, "List of X.509 CA Information Records:\n");
-                                       fprintf(out, "\n");
-                                       first = FALSE;
-                               }
-                               ca_info->list(ca_info, out, msg->list.utc);
-                       }
-               }
-               iterator->destroy(iterator);
-       }
-       if (msg->list.flags & LIST_CRLS)
-       {
-        ca_info_t *ca_info;
-        bool first = TRUE;
-
-        iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
-        while (iterator->iterate(iterator, (void **)&ca_info))
-        {
-            if (ca_info->is_ca(ca_info) && ca_info->has_crl(ca_info))
-            {
-                if (first)
-                {
-                    fprintf(out, "\n");
-                    fprintf(out, "List of X.509 CRLs:\n");
-                    fprintf(out, "\n");
-                    first = FALSE;
-                }
-                ca_info->list_crl(ca_info, out, msg->list.utc);
-            }
-        }
-        iterator->destroy(iterator);
-       }
-       if (msg->list.flags & LIST_OCSP)
-       {
-               ca_info_t *ca_info;
-               bool first = TRUE;
-
-        iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
-        while (iterator->iterate(iterator, (void **)&ca_info))
-        {
-            if (ca_info->is_ca(ca_info) && ca_info->has_certinfos(ca_info))
-            {
-                if (first)
-                {
-                    fprintf(out, "\n");
-                    fprintf(out, "List of OCSP responses:\n");
-                    first = FALSE;
-                }
-                fprintf(out, "\n");
-                ca_info->list_certinfos(ca_info, out, msg->list.utc);
-            }
-        }
-        iterator->destroy(iterator);
-       }
-}
-
-/**
- * reread various information
- */
-static void stroke_reread(stroke_msg_t *msg, FILE *out)
-{
-       if (msg->reread.flags & REREAD_SECRETS)
-       {
-               charon->credentials->load_secrets(charon->credentials, TRUE);
-       }
-       if (msg->reread.flags & REREAD_CACERTS)
-       {
-               charon->credentials->load_ca_certificates(charon->credentials);
-       }
-       if (msg->reread.flags & REREAD_OCSPCERTS)
-       {
-               charon->credentials->load_ocsp_certificates(charon->credentials);
-       }
-       if (msg->reread.flags & REREAD_AACERTS)
-       {
-               charon->credentials->load_aa_certificates(charon->credentials);
-       }
-       if (msg->reread.flags & REREAD_ACERTS)
-       {
-               charon->credentials->load_attr_certificates(charon->credentials);
-       }
-       if (msg->reread.flags & REREAD_CRLS)
-       {
-               charon->credentials->load_crls(charon->credentials);
-       }
-}
-
-/**
- * purge various information
- */
-static void stroke_purge(stroke_msg_t *msg, FILE *out)
-{
-       if (msg->purge.flags & PURGE_OCSP)
-       {
-               iterator_t *iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
-               ca_info_t *ca_info;
-
-               while (iterator->iterate(iterator, (void**)&ca_info))
-               {
-                       if (ca_info->is_ca(ca_info))
-                       {
-                               ca_info->purge_ocsp(ca_info);
-                       }
-               }
-               iterator->destroy(iterator);
-       }
-}
-
-signal_t get_signal_from_logtype(char *type)
-{
-       if      (strcasecmp(type, "any") == 0) return SIG_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;
-       else return -1;
-}
-
-/**
- * set the verbosity debug output
- */
-static void stroke_loglevel(stroke_msg_t *msg, FILE *out)
-{
-       signal_t signal;
-       
-       pop_string(msg, &(msg->loglevel.type));
-       DBG1(DBG_CFG, "received stroke: loglevel %d for %s",
-                msg->loglevel.level, msg->loglevel.type);
-       
-       signal = get_signal_from_logtype(msg->loglevel.type);
-       if (signal < 0)
-       {
-               fprintf(out, "invalid type (%s)!\n", msg->loglevel.type);
-               return;
-       }
-       
-       charon->outlog->set_level(charon->outlog, signal, msg->loglevel.level);
-       charon->syslog->set_level(charon->syslog, signal, msg->loglevel.level);
-}
-
-/**
- * process a stroke request from the socket pointed by "fd"
- */
-static job_requeue_t stroke_process(int *fdp)
-{
-       stroke_msg_t *msg;
-       u_int16_t msg_length;
-       ssize_t bytes_read;
-       FILE *out;
-       int strokefd = *fdp;
-       
-       /* peek the length */
-       bytes_read = recv(strokefd, &msg_length, sizeof(msg_length), MSG_PEEK);
-       if (bytes_read != sizeof(msg_length))
-       {
-               DBG1(DBG_CFG, "reading length of stroke message failed: %s",
-                        strerror(errno));
-               close(strokefd);
-               return JOB_REQUEUE_NONE;
-       }
-       
-       /* read message */
-       msg = malloc(msg_length);
-       bytes_read = recv(strokefd, msg, msg_length, 0);
-       if (bytes_read != msg_length)
-       {
-               DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno));
-               close(strokefd);
-               return JOB_REQUEUE_NONE;
-       }
-       
-       out = fdopen(strokefd, "w");
-       if (out == NULL)
-       {
-               DBG1(DBG_CFG, "opening stroke output channel failed: %s", strerror(errno));
-               close(strokefd);
-               free(msg);
-               return JOB_REQUEUE_NONE;
-       }
-       
-       DBG3(DBG_CFG, "stroke message %b", (void*)msg, msg_length);
-       
-       /* the stroke_* functions are blocking, as they listen on the bus. Add
-        * cancellation handlers. */
-       pthread_cleanup_push((void*)fclose, out);
-       pthread_cleanup_push(free, msg);
-       
-       switch (msg->type)
-       {
-               case STR_INITIATE:
-                       stroke_initiate(msg, out);
-                       break;
-               case STR_ROUTE:
-                       stroke_route(msg, out);
-                       break;
-               case STR_UNROUTE:
-                       stroke_unroute(msg, out);
-                       break;
-               case STR_TERMINATE:
-                       stroke_terminate(msg, out);
-                       break;
-               case STR_STATUS:
-                       stroke_status(msg, out, FALSE);
-                       break;
-               case STR_STATUS_ALL:
-                       stroke_status(msg, out, TRUE);
-                       break;
-               case STR_ADD_CONN:
-                       stroke_add_conn(msg, out);
-                       break;
-               case STR_DEL_CONN:
-                       stroke_del_conn(msg, out);
-                       break;
-               case STR_ADD_CA:
-                       stroke_add_ca(msg, out);
-                       break;
-               case STR_DEL_CA:
-                       stroke_del_ca(msg, out);
-                       break;
-               case STR_LOGLEVEL:
-                       stroke_loglevel(msg, out);
-                       break;
-               case STR_LIST:
-                       stroke_list(msg, out);
-                       break;
-               case STR_REREAD:
-                       stroke_reread(msg, out);
-                       break;
-               case STR_PURGE:
-                       stroke_purge(msg, out);
-                       break;
-               default:
-                       DBG1(DBG_CFG, "received unknown stroke");
-       }
-       /* remove and execute cancellation handlers */
-       pthread_cleanup_pop(1);
-       pthread_cleanup_pop(1);
-       
-       return JOB_REQUEUE_NONE;
-}
-
-/**
- * Implementation of private_stroke_interface_t.stroke_receive.
- */
-static job_requeue_t stroke_receive(private_stroke_interface_t *this)
-{
-       struct sockaddr_un strokeaddr;
-       int strokeaddrlen = sizeof(strokeaddr);
-       int strokefd, *fdp;
-       int oldstate;
-       callback_job_t *job;
-       
-       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
-       strokefd = accept(this->socket, (struct sockaddr *)&strokeaddr, &strokeaddrlen);
-       pthread_setcancelstate(oldstate, NULL);
-       
-       if (strokefd < 0)
-       {
-               DBG1(DBG_CFG, "accepting stroke connection failed: %s", strerror(errno));
-               return JOB_REQUEUE_FAIR;
-       }
-       
-       fdp = malloc_thing(int);
-       *fdp = strokefd;
-       job = callback_job_create((callback_job_cb_t)stroke_process, fdp, free, this->job);
-       charon->processor->queue_job(charon->processor, (job_t*)job);
-       
-       return JOB_REQUEUE_FAIR;
-}
-
-/**
- * Implementation of interface_t.destroy.
- */
-static void destroy(private_stroke_interface_t *this)
-{
-       this->job->cancel(this->job);
-       free(this);
-}
-
-/*
- * Described in header-file
- */
-interface_t *interface_create()
-{
-       struct sockaddr_un socket_addr = { AF_UNIX, STROKE_SOCKET};
-       private_stroke_interface_t *this = malloc_thing(private_stroke_interface_t);
-       mode_t old;
-
-       /* public functions */
-       this->public.interface.destroy = (void (*)(interface_t*))destroy;
-       
-       /* set up unix socket */
-       this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (this->socket == -1)
-       {
-               DBG1(DBG_CFG, "could not create stroke socket");
-               free(this);
-               return NULL;
-       }
-       
-       unlink(socket_addr.sun_path);
-       old = umask(~(S_IRWXU | S_IRWXG));
-       if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
-       {
-               DBG1(DBG_CFG, "could not bind stroke socket: %s", strerror(errno));
-               close(this->socket);
-               free(this);
-               return NULL;
-       }
-       umask(old);
-       if (chown(socket_addr.sun_path, IPSEC_UID, IPSEC_GID) != 0)
-       {
-               DBG1(DBG_CFG, "changing stroke socket permissions failed: %s",
-                        strerror(errno));
-       }
-       
-       if (listen(this->socket, 0) < 0)
-       {
-               DBG1(DBG_CFG, "could not listen on stroke socket: %s", strerror(errno));
-               close(this->socket);
-               unlink(socket_addr.sun_path);
-               free(this);
-               return NULL;
-       }
-       
-       this->job = callback_job_create((callback_job_cb_t)stroke_receive,
-                                                                       this, NULL, NULL);
-       charon->processor->queue_job(charon->processor, (job_t*)this->job);
-       
-       return &this->public.interface;
-}
-
diff --git a/src/charon/credentials/auth_info.c b/src/charon/credentials/auth_info.c
new file mode 100644 (file)
index 0000000..a0fc4c0
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * 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$
+ */
+
+
+#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_CA_CERT",
+       "AUTHN_IM_CERT",
+       "AUTHN_SUBJECT_CERT",
+       "AUTHZ_PUBKEY",
+       "AUTHZ_PSK",
+       "AUTHZ_EAP",
+       "AUTHZ_CA_CERT",
+       "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;
+};
+
+/**
+ * implements item_enumerator_t.enumerate
+ */
+static bool item_filter(void *data, item_t **item, auth_item_t *type,
+                                                                       void *unused, void **value)
+{
+       *type = (*item)->type;
+       *value = (*item)->value;
+       return TRUE;
+}
+
+/**
+ * Implementation of auth_info_t.create_item_enumerator.
+ */
+static enumerator_t* create_item_enumerator(private_auth_info_t *this)
+{
+       return enumerator_create_filter(this->items->create_enumerator(this->items),
+                                                                       (void*)item_filter, NULL, NULL);
+}
+
+/**
+ * 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_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 AUTHZ_EAP:
+               {
+                       eap_method_t *method = malloc_thing(eap_method_t);
+
+                       *method = *(eap_method_t*)value;
+                       item->value = method;
+                       break;
+               }
+               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 type;
+       void *value;
+       
+       enumerator = constraints->create_item_enumerator(constraints);
+       while (enumerator->enumerate(enumerator, &type, &value))
+       {
+               switch (type)
+               {
+                       case AUTHN_CA_CERT:
+                       case AUTHN_IM_CERT:
+                       case AUTHN_SUBJECT_CERT:
+                       {       /* 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, type, (void**)&valid) &&
+                                       type == 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, type,
+                                                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, type,
+                                                        cert_validation_names, *valid,
+                                                        cert_validation_names, *(cert_validation_t*)value);
+                                               success = FALSE;
+                                               break;
+                               }
+                               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, type);
+                               success = FALSE;
+                               break;
+                       case AUTHZ_CA_CERT:
+                       {
+                               certificate_t *cert;
+                       
+                               if (!get_item(this, AUTHZ_CA_CERT, (void**)&cert) ||
+                                       !cert->equals(cert, (certificate_t*)value))
+                               {
+                                       cert = (certificate_t*)value;
+                                       DBG1(DBG_CFG, "constraint check failed: peer not "
+                                                "authenticated by CA '%D'.", cert->get_issuer(cert));
+                                       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.destroy
+ */
+static void destroy(private_auth_info_t *this)
+{
+       item_t *item;
+       
+       while (this->items->remove_last(this->items, (void**)&item) == SUCCESS)
+       {
+               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 AUTHZ_CRL_VALIDATION:
+                       case AUTHZ_OCSP_VALIDATION:
+                       case AUTHZ_EAP:
+                       {
+                               free(item->value);
+                               break;
+                       }
+                       case AUTHZ_AC_GROUP:
+                       {
+                               identification_t *id = (identification_t*)item->value;
+                               id->destroy(id);
+                               break;
+                       }
+               }
+               free(item);
+       }
+       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.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.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
new file mode 100644 (file)
index 0000000..f8ba29d
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * 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
+        */
+       
+       /** CA certificate to use for authentication, value is certificate_t* */
+       AUTHN_CA_CERT,
+       /** intermediate certificate, value is certificate_t* */
+       AUTHN_IM_CERT,
+       /** certificate for trustchain verification, value is certificate_t* */
+       AUTHN_SUBJECT_CERT,
+       
+       /*
+        * 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_method_t */
+       AUTHZ_EAP,
+       /** certificate authority, value is certificate_t* */
+       AUTHZ_CA_CERT,
+       /** 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);
+       
+       /**
+        * 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);
+       
+       /**
+     * 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
new file mode 100644 (file)
index 0000000..e5db235
--- /dev/null
@@ -0,0 +1,1385 @@
+/*
+ * 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$
+ */
+
+#include "credential_manager.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+#include <credentials/certificates/ocsp_request.h>
+#include <credentials/certificates/ocsp_response.h>
+
+#define MAX_CA_LEVELS 6
+
+typedef struct private_credential_manager_t private_credential_manager_t;
+
+/**
+ * private data of credential_manager
+ */
+struct private_credential_manager_t {
+
+       /**
+        * public functions
+        */
+       credential_manager_t public;
+       
+       /**
+        * list of credential sets
+        */
+       linked_list_t *sets;
+       
+       /**
+        * mutex to gain exclusive access
+        */
+       mutex_t *mutex;
+};
+
+/** data to pass to create_private_enumerator */
+typedef struct {
+       private_credential_manager_t *this;
+       key_type_t type;
+       identification_t* keyid;
+} private_data_t;
+
+/** data to pass to create_cert_enumerator */
+typedef struct {
+       private_credential_manager_t *this;
+       certificate_type_t cert;
+       key_type_t key;
+       identification_t *id;
+       bool trusted;
+} cert_data_t;
+
+/** data to pass to create_cdp_enumerator */
+typedef struct {
+       private_credential_manager_t *this;
+       certificate_type_t type;
+       identification_t *id;
+} cdp_data_t;
+
+/** data to pass to create_shared_enumerator */
+typedef struct {
+       private_credential_manager_t *this;
+       shared_key_type_t type;
+       identification_t *me;
+       identification_t *other;
+} shared_data_t;
+
+/**
+ * cleanup function for cert data
+ */
+static void destroy_cert_data(cert_data_t *data)
+{
+       data->this->mutex->unlock(data->this->mutex);
+       free(data);
+}
+
+/**
+ * enumerator constructor for certificates
+ */
+static enumerator_t *create_cert(credential_set_t *set, cert_data_t *data)
+{
+       return set->create_cert_enumerator(set, data->cert, data->key, 
+                                                                          data->id, data->trusted);
+}
+
+/**
+ * Implementation of credential_manager_t.create_cert_enumerator.
+ */
+static enumerator_t *create_cert_enumerator(private_credential_manager_t *this,
+                                               certificate_type_t certificate, key_type_t key,
+                                               identification_t *id, bool trusted)
+{
+       cert_data_t *data = malloc_thing(cert_data_t);
+       data->this = this;
+       data->cert = certificate;
+       data->key = key;
+       data->id = id;
+       data->trusted = trusted;
+       
+       this->mutex->lock(this->mutex);
+       return enumerator_create_nested(this->sets->create_enumerator(this->sets),
+                                                                       (void*)create_cert, data,
+                                                                       (void*)destroy_cert_data);
+}
+
+/**
+ * Implementation of credential_manager_t.get_cert.
+ */
+static certificate_t *get_cert(private_credential_manager_t *this,
+                                               certificate_type_t cert, key_type_t key,
+                                               identification_t *id, bool trusted)
+{
+       certificate_t *current, *found = NULL;
+       enumerator_t *enumerator;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = create_cert_enumerator(this, cert, key, id, trusted);
+       if (enumerator->enumerate(enumerator, &current))
+       {
+               /* TODO: best match? order by keyid, subject, sualtname */
+               found = current->get_ref(current);
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return found;
+}
+
+
+/**
+ * cleanup function for cdp data
+ */
+static void destroy_cdp_data(cdp_data_t *data)
+{
+       data->this->mutex->unlock(data->this->mutex);
+       free(data);
+}
+
+/**
+ * enumerator constructor for CDPs
+ */
+static enumerator_t *create_cdp(credential_set_t *set, cdp_data_t *data)
+{
+       return set->create_cdp_enumerator(set, data->type, data->id);
+}
+/**
+ * Implementation of credential_manager_t.create_cdp_enumerator.
+ */
+static enumerator_t * create_cdp_enumerator(private_credential_manager_t *this,
+                                                               credential_type_t type, identification_t *id)
+{
+       cdp_data_t *data = malloc_thing(cdp_data_t);
+       data->this = this;
+       data->type = type;
+       data->id = id;
+       
+       this->mutex->lock(this->mutex);
+       return enumerator_create_nested(this->sets->create_enumerator(this->sets),
+                                                                       (void*)create_cdp, data,
+                                                                       (void*)destroy_cdp_data);
+}
+
+/**
+ * cleanup function for private data
+ */
+static void destroy_private_data(private_data_t *data)
+{
+       data->this->mutex->unlock(data->this->mutex);
+       free(data);
+}
+
+/**
+ * enumerator constructor for private keys
+ */
+static enumerator_t *create_private(credential_set_t *set, private_data_t *data)
+{
+       return set->create_private_enumerator(set, data->type, data->keyid);
+}
+
+/**
+ * Implementation of credential_manager_t.get_private_by_keyid.
+ */
+static enumerator_t* create_private_enumerator(
+                                                                       private_credential_manager_t *this,
+                                                                   key_type_t key, identification_t *keyid)
+{
+       private_data_t *data;
+       
+       data = malloc_thing(private_data_t);
+       data->this = this;
+       data->type = key;
+       data->keyid = keyid;
+       this->mutex->lock(this->mutex);
+       return enumerator_create_nested(this->sets->create_enumerator(this->sets),
+                                               (void*)create_private, data, (void*)destroy_private_data);
+}
+
+/**
+ * Implementation of credential_manager_t.get_private_by_keyid.
+ */   
+static private_key_t *get_private_by_keyid(private_credential_manager_t *this,
+                                                                                  key_type_t key, identification_t *keyid)
+{
+       private_key_t *found = NULL;
+       enumerator_t *enumerator;
+       
+       enumerator = create_private_enumerator(this, key, keyid);
+       if (enumerator->enumerate(enumerator, &found))
+       {
+               found->get_ref(found);
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
+/**
+ * cleanup function for shared data
+ */
+static void destroy_shared_data(shared_data_t *data)
+{
+       data->this->mutex->unlock(data->this->mutex);
+       free(data);
+}
+
+/**
+ * enumerator constructor for shared keys
+ */
+static enumerator_t *create_shared(credential_set_t *set, shared_data_t *data)
+{
+       return set->create_shared_enumerator(set, data->type, data->me, data->other);
+}
+
+/**
+ * Implementation of credential_manager_t.create_shared_enumerator.
+ */
+static enumerator_t *create_shared_enumerator(private_credential_manager_t *this, 
+                                               shared_key_type_t type,
+                                               identification_t *me, identification_t *other)
+{
+       shared_data_t *data = malloc_thing(shared_data_t);
+       data->this = this;
+       data->type = type;
+       data->me = me;
+       data->other = other;
+       
+       this->mutex->lock(this->mutex);
+       return enumerator_create_nested(this->sets->create_enumerator(this->sets),
+                                                                       (void*)create_shared, data, 
+                                                                       (void*)destroy_shared_data);
+}
+
+/**
+ * Implementation of credential_manager_t.get_shared.
+ */   
+static shared_key_t *get_shared(private_credential_manager_t *this,
+                                                               shared_key_type_t type, identification_t *me,
+                                                               identification_t *other)
+{
+       shared_key_t *current, *found = NULL;
+       id_match_t *best_me = ID_MATCH_NONE, *best_other = ID_MATCH_NONE;
+       id_match_t *match_me, *match_other;
+       enumerator_t *enumerator;
+       
+       enumerator = create_shared_enumerator(this, type, me, other);
+       while (enumerator->enumerate(enumerator, &current, &match_me, &match_other))
+       {
+               if (match_other > best_other ||
+                       (match_other == best_other && match_me > best_me))
+               {
+                       DESTROY_IF(found);
+                       found = current->get_ref(current);
+                       best_me = match_me;
+                       best_other = match_other;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
+/**
+ * forward declaration 
+ */
+static certificate_t *get_trusted_cert(private_credential_manager_t *this,
+                                                                          key_type_t type, identification_t *id,
+                                                                          auth_info_t *auth, bool crl, bool ocsp);
+/**
+ * return null ;-)
+ */
+static void *return_null()
+{
+       return NULL;
+}
+
+/**
+ * credential_set_t implementation around an OCSP response
+ */
+typedef struct ocsp_wrapper_t {
+       credential_set_t set;
+       ocsp_response_t *response;
+} ocsp_wrapper_t;
+
+/**
+ * enumerator for ocsp_wrapper_t.create_cert_enumerator()
+ */
+typedef struct {
+       enumerator_t public;
+       enumerator_t *inner;
+       certificate_type_t cert;
+       key_type_t key;
+       identification_t *id;
+} ocsp_wrapper_enumerator_t;
+
+/**
+ * enumerate function for ocsp_wrapper_enumerator_t
+ */
+static bool ocsp_wrapper_enum_enumerate(ocsp_wrapper_enumerator_t *this,
+                                                                           certificate_t **cert)
+{
+       certificate_t *current;
+       public_key_t *public;
+
+       while (this->inner->enumerate(this->inner, &current))
+       {
+               if (this->cert != CERT_ANY && this->cert != current->get_type(current))
+               {       /* CERT type requested, but does not match */
+                       continue;
+               }
+               public = current->get_public_key(current);
+               if (this->key != KEY_ANY && !public)
+               {       /* key type requested, but no public key */
+                       DESTROY_IF(public);
+                       continue;
+               }
+               if (this->key != KEY_ANY && public && this->key != public->get_type(public))
+               {       /* key type requested, but public key has another type */
+                       DESTROY_IF(public);
+                       continue;
+               }
+               DESTROY_IF(public);
+               if (this->id && !current->has_subject(current, this->id))
+               {       /* subject requested, but does not match */
+                       continue;
+               }
+               *cert = current;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * destroy function for ocsp_wrapper_enumerator_t
+ */
+static void ocsp_wrapper_enum_destroy(ocsp_wrapper_enumerator_t *this)
+{
+       this->inner->destroy(this->inner);
+       free(this);
+}
+
+/**
+ * implementation of ocsp_wrapper_t.set.create_cert_enumerator
+ */
+static enumerator_t *ocsp_wrapper_create_enumerator(ocsp_wrapper_t *this,
+                                                                               certificate_type_t cert, key_type_t key,
+                                                                               identification_t *id, bool trusted)
+{
+       ocsp_wrapper_enumerator_t *enumerator;
+       
+       if (trusted)
+       {
+               return NULL;
+       }
+       
+       enumerator = malloc_thing(ocsp_wrapper_enumerator_t);
+       enumerator->cert = cert;
+       enumerator->key = key;
+       enumerator->id = id;
+       enumerator->inner = this->response->create_cert_enumerator(this->response);
+       enumerator->public.enumerate = (void*)ocsp_wrapper_enum_enumerate;
+       enumerator->public.destroy = (void*)ocsp_wrapper_enum_destroy;
+       return &enumerator->public;
+}
+
+/**
+ * create credential_set wrapper around an OCSP response
+ */
+static ocsp_wrapper_t *ocsp_wrapper_create(ocsp_response_t *response)
+{
+       ocsp_wrapper_t *this = malloc_thing(ocsp_wrapper_t);
+       
+       this->response = response;
+       this->set.create_private_enumerator = (void*)return_null;
+       this->set.create_cert_enumerator = (void*)ocsp_wrapper_create_enumerator;
+       this->set.create_shared_enumerator = (void*)return_null;
+       this->set.create_cdp_enumerator = (void*)return_null;
+
+       return this;
+}
+
+/**
+ * Do an OCSP request
+ */
+static ocsp_response_t *fetch_ocsp(private_credential_manager_t *this, char *url,
+                                                                  certificate_t *subject, certificate_t *issuer)
+{
+       certificate_t *request, *response, *issuer_cert;
+       chunk_t send, receive;
+       identification_t *responder;
+       auth_info_t *auth;
+       ocsp_wrapper_t *wrapper;
+       
+       /* TODO: requestor name, signature */
+       request = lib->creds->create(lib->creds,
+                                               CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
+                                               BUILD_CA_CERT, issuer->get_ref(issuer),
+                                               BUILD_CERT, subject->get_ref(subject), BUILD_END);
+       if (!request)
+       {
+               DBG1(DBG_CFG, "generating OCSP request failed");
+               return NULL;
+       }
+       
+       send = request->get_encoding(request);
+       request->destroy(request);
+       if (lib->fetcher->fetch(lib->fetcher, url, &receive, 
+                                                       FETCH_REQUEST_DATA, send,
+                                                       FETCH_REQUEST_TYPE, "application/ocsp-request",
+                                                       FETCH_END) != SUCCESS)
+       {
+               DBG1(DBG_CFG, "OCSP request to %s failed", url);
+               chunk_free(&send);
+               return NULL;
+       }
+       chunk_free(&send);
+       
+       response = lib->creds->create(lib->creds,
+                                                                 CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
+                                                                 BUILD_BLOB_ASN1_DER, receive, BUILD_END);
+       if (!response)
+       {
+               DBG1(DBG_CFG, "parsing OCSP response from %s failed", url);
+               return NULL;
+       }
+       
+       responder = response->get_issuer(response);
+       auth = auth_info_create();
+       wrapper = ocsp_wrapper_create((ocsp_response_t*)response);
+       this->sets->insert_first(this->sets, wrapper);
+       issuer_cert = get_trusted_cert(this, KEY_ANY, responder, auth, FALSE, FALSE);
+       this->sets->remove(this->sets, wrapper, NULL);
+       free(wrapper);
+       auth->destroy(auth);
+       if (!issuer_cert)
+       {
+               DBG1(DBG_CFG, "verifying OCSP response failed, no trusted "
+                        "certificate found");
+               response->destroy(response);
+               return NULL;
+       }
+       if (!response->issued_by(response, issuer_cert, TRUE))
+       {
+               DBG1(DBG_CFG, "verifying OCSP response signature failed");
+               response->destroy(response);
+               issuer_cert->destroy(issuer_cert);
+               return NULL;
+       }
+       issuer_cert->destroy(issuer_cert);
+       
+       /* TODO: cache response? */
+       
+       return (ocsp_response_t*)response;
+}
+
+/**
+ * validate a x509 certificate using OCSP
+ */
+static cert_validation_t check_ocsp(private_credential_manager_t *this,
+                                                                   x509_t *subject, x509_t *issuer, 
+                                                                   auth_info_t *auth)
+{
+       public_key_t *public;
+       enumerator_t *enumerator;
+       ocsp_response_t *response = NULL;
+       certificate_t *cert, *sub = (certificate_t*)subject;
+       cert_validation_t valid = VALIDATION_SKIPPED;
+       identification_t *keyid = NULL;
+       char *url;
+       
+       cert = &issuer->interface;
+       public = cert->get_public_key(cert);
+       if (public)
+       {
+               keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+       }
+       
+       /* find a OCSP response by Authority key identifier (cache) */  
+       if (keyid)
+       {
+               time_t update, best_update = 0;
+
+               enumerator = create_cert_enumerator(this, CERT_X509_OCSP_RESPONSE,
+                                                                                       KEY_ANY, keyid, TRUE);
+               while (enumerator->enumerate(enumerator, &cert))
+               {       /* get newest valid response */
+                       if (cert->has_subject(cert, sub->get_subject(sub)) &&
+                               cert->get_validity(cert, NULL, &update, NULL) &&
+                               update > best_update)
+                       {
+                               best_update = update;
+                               DESTROY_IF(&response->certificate);
+                               response = (ocsp_response_t*)cert;
+                               valid = VALIDATION_FAILED;
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+       /* fallback to URL fetching from CDPs */
+       if (!response && keyid)
+       {
+               enumerator = create_cdp_enumerator(this, CERT_X509_OCSP_RESPONSE, keyid);
+               while (enumerator->enumerate(enumerator, &url))
+               {
+                       valid = VALIDATION_FAILED;
+                       response = fetch_ocsp(this, url, &subject->interface, &issuer->interface);
+                       if (response)
+                       {
+                               break;
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+       /* fallback to URL fetching from subject certificate's URIs */
+       if (!response)
+       {
+               enumerator = subject->create_ocsp_uri_enumerator(subject);
+               while (enumerator->enumerate(enumerator, &url))
+               {
+                       valid = VALIDATION_FAILED;
+                       response = fetch_ocsp(this, url, &subject->interface, &issuer->interface);
+                       if (response)
+                       {
+                               break;
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+       /* look for subject in response */
+       if (response)
+       {
+               time_t revocation, this_update, next_update;
+               crl_reason_t reason;
+               
+               valid = response->get_status(response, subject, issuer, &revocation,
+                                                                        &reason, &this_update, &next_update);
+               switch (valid)
+               {
+                       case VALIDATION_FAILED:
+                               DBG1(DBG_CFG, "subject not found in OCSP response");
+                               break;
+                       case VALIDATION_REVOKED:
+                               DBG1(DBG_CFG, "certificate %D revoked by OCSP at %T: %N",
+                                        cert->get_subject(cert), &revocation,
+                                        crl_reason_names, reason);
+                               break;
+                       case VALIDATION_GOOD:
+                               break;
+                       default:
+                               break;
+               }
+               cert = (certificate_t*)response;
+               cert->destroy(cert);
+       }
+       DESTROY_IF(public);
+       if (auth)
+       {
+               auth->add_item(auth, AUTHZ_OCSP_VALIDATION, &valid);
+       }
+       return valid;
+}
+
+/**
+ * fetch a CRL from an URL
+ */
+static certificate_t* fetch_crl(private_credential_manager_t *this, char *url)
+{
+       certificate_t *crl_cert;
+       chunk_t chunk;
+       
+       /* TODO: unlock the manager while fetching? */
+       DBG1(DBG_CFG, "fetching crl from '%s' ...", url);
+       if (lib->fetcher->fetch(lib->fetcher, url, &chunk, FETCH_END) != SUCCESS)
+       {
+               DBG1(DBG_CFG, "  crl fetching failed");
+               return NULL;
+       }
+       crl_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+                                                                 BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+       if (!crl_cert)
+       {
+               DBG1(DBG_CFG, "  crl fetched successfully but parsing failed");
+               return NULL;
+       }
+       
+       /* verify the signature of the fetched crl */
+       {
+               bool ok;
+               identification_t *issuer = crl_cert->get_issuer(crl_cert);
+               auth_info_t *auth = auth_info_create();
+               certificate_t *issuer_cert = get_trusted_cert(this, KEY_ANY, issuer,
+                                                                                                         auth, FALSE, FALSE);
+               auth->destroy(auth);
+
+               if (!issuer_cert)
+               {
+                       DBG1(DBG_CFG, "  crl is untrusted: issuer certificate not found");
+                       crl_cert->destroy(crl_cert);
+                       return NULL;
+               }
+               ok = crl_cert->issued_by(crl_cert, issuer_cert, TRUE);
+               issuer_cert->destroy(issuer_cert);
+
+               DBG1(DBG_CFG, "  crl is %strusted: %s signature",
+                                          ok ? "":"un", ok ? "good" : "bad");
+               if (!ok)
+               {
+                       crl_cert->destroy(crl_cert);
+                       return NULL;
+               }
+       }
+       return crl_cert;
+}
+
+/**
+ * validate a x509 certificate using CRL
+ */
+static cert_validation_t check_crl(private_credential_manager_t *this,
+                                                                  x509_t *subject, x509_t *issuer, 
+                                                                  auth_info_t *auth)
+{
+       identification_t *keyid = NULL;
+       certificate_t *best_cert = NULL;
+       cert_validation_t valid = VALIDATION_SKIPPED;
+       bool stale = TRUE;
+       
+       /* derive the authorityKeyIdentifier from the issuer's public key */
+       {
+               certificate_t *cert = &issuer->interface;
+               public_key_t *public = cert->get_public_key(cert);
+
+               if (public)
+               {
+                       keyid = public->get_id(public, ID_PUBKEY_SHA1);
+                       public->destroy(public);
+               }
+       }
+       
+       /* find a local crl by authorityKeyIdentifier */
+       if (keyid)
+       {
+               enumerator_t *enumerator = create_cert_enumerator(this, CERT_X509_CRL,
+                                                                                                               KEY_ANY, keyid, TRUE);
+               certificate_t *cert;
+
+               while (enumerator->enumerate(enumerator, &cert))
+               {
+                       crl_t *crl = (crl_t*)cert;
+                       crl_t *best_crl = (crl_t*)best_cert;
+       
+                       /* select most recent crl */
+                       if (best_cert == NULL || crl->is_newer(crl, best_crl))
+                       {
+                               DESTROY_IF(best_cert);
+                               best_cert = cert->get_ref(cert);
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+
+       /* check the validity of the local crl if one was found */
+       if (best_cert)
+       {
+               stale = !best_cert->get_validity(best_cert, NULL, NULL, NULL);
+               DBG1(DBG_CFG, "locally-stored crl is %s", stale? "stale":"valid");
+       }
+       else
+       {
+               DBG1(DBG_CFG, "no locally-stored crl found");
+       }
+
+       /* fallback to fetching crls from cdps defined in ca info sections */
+       if (stale && keyid)
+       {
+               enumerator_t *enumerator = create_cdp_enumerator(this, CERT_X509_CRL,
+                                                                                                                keyid);
+               char *uri;
+
+               while (enumerator->enumerate(enumerator, &uri))
+               {
+                       certificate_t *cert = fetch_crl(this, uri);
+
+                       /* redefine default since we have at least one uri */
+                       valid = VALIDATION_FAILED;
+
+                       if (cert)
+                       {
+                               crl_t *crl = (crl_t*)cert;
+                               crl_t *best_crl = (crl_t*)best_cert;
+
+                               /* select most recent crl */
+                               if (best_cert == NULL || crl->is_newer(crl, best_crl))
+                               {
+                                       DESTROY_IF(best_cert);
+                                       best_cert = cert;
+                                       stale = !best_cert->get_validity(best_cert, NULL, NULL, NULL);
+                                       DBG1(DBG_CFG, "fetched crl is %s", stale? "stale":"valid");
+                                       if (!stale)
+                                       {
+                                               break;
+                                       }
+                               }
+                               else
+                               {
+                                       cert->destroy(cert);
+                               }
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+
+       /* fallback to fetching crls from cdps defined in the subject's certificate */
+       if (stale)
+       {
+               enumerator_t *enumerator = subject->create_crl_uri_enumerator(subject);
+               char *uri;
+
+               while (enumerator->enumerate(enumerator, &uri))
+               {
+                       certificate_t *cert = fetch_crl(this, uri);
+
+                       /* redefine default since we have at least one uri */
+                       valid = VALIDATION_FAILED;
+
+                       if (cert)
+                       {
+                               crl_t *crl = (crl_t*)cert;
+                               crl_t *best_crl = (crl_t*)best_cert;
+
+                               /* select most recent crl */
+                               if (best_cert == NULL || crl->is_newer(crl, best_crl))
+                               {
+                                       DESTROY_IF(best_cert);
+                                       best_cert = cert;
+                                       stale = !best_cert->get_validity(best_cert, NULL, NULL, NULL);
+                                       DBG1(DBG_CFG, "fetched crl is %s", stale? "stale":"valid");
+                                       if (!stale)
+                                       {
+                                               break;
+                                       }
+                               }
+                               else
+                               {
+                                       cert->destroy(cert);
+                               }
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+
+       /* if we have a crl, check the revocation status */
+       if (best_cert)
+       {
+               chunk_t serial;
+               time_t revocation;
+               crl_reason_t reason;
+               crl_t *crl = (crl_t*)best_cert;
+               enumerator_t *enumerator = crl->create_enumerator(crl);
+
+               /* redefine default */
+               valid = stale ? VALIDATION_UNKNOWN : VALIDATION_GOOD;
+
+               while (enumerator->enumerate(enumerator, &serial, &revocation, &reason))
+               {
+                       if (chunk_equals(serial, subject->get_serial(subject)))
+                       {
+                               DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
+                                        &revocation, crl_reason_names, reason);
+                               valid = VALIDATION_REVOKED;
+                               break;
+                       }
+               }
+               enumerator->destroy(enumerator);
+               best_cert->destroy(best_cert);
+       }
+
+       if (auth)
+       {
+               auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
+       }
+       return valid;
+}
+
+/**
+ * check a certificate for its lifetime
+ */
+static bool check_certificate(private_credential_manager_t *this,
+                                                         certificate_t *subject, certificate_t *issuer,
+                                                         bool crl, bool ocsp, auth_info_t *auth)
+{
+       time_t not_before, not_after;
+
+       if (!subject->get_validity(subject, NULL, &not_before, &not_after))
+       {
+               DBG1(DBG_CFG, "certificate invalid (valid from %T to %T)",
+                        &not_before, &not_after);
+               return FALSE;
+       }
+       if (issuer && !subject->issued_by(subject, issuer, TRUE))
+       {
+               DBG1(DBG_CFG, "certificate %D not issued by %D",
+                        subject->get_subject(subject), issuer->get_subject(issuer));
+               return FALSE;
+       }
+       if (issuer && issuer->get_type(issuer) == CERT_X509 &&
+               subject->get_type(subject) == CERT_X509)
+       {
+               if (ocsp)
+               {
+                       switch (check_ocsp(this, (x509_t*)subject, (x509_t*)issuer, auth))
+                       {
+                               case VALIDATION_GOOD:
+                                       DBG1(DBG_CFG, "certificate %D validated by OCSP",
+                                                subject->get_subject(subject));
+                                       return TRUE;
+                               case VALIDATION_REVOKED:
+                                       return FALSE;
+                               case VALIDATION_SKIPPED:
+                                       DBG2(DBG_CFG, "OCSP check skipped, no OCSP URI found");
+                                       break;
+                               case VALIDATION_FAILED:
+                                       DBG1(DBG_CFG, "OCSP check failed, fallback to CRL");
+                                       break;
+                       }
+               }
+               if (crl)
+               {
+                       switch (check_crl(this, (x509_t*)subject, (x509_t*)issuer, auth))
+                       {
+                               case VALIDATION_GOOD:
+                                       DBG1(DBG_CFG, "certificate status is good");
+                                       break;
+                               case VALIDATION_REVOKED:                
+                                       /* has already been logged */                   
+                                       break;
+                               case VALIDATION_UNKNOWN:
+                                       DBG1(DBG_CFG, "certificate status is unknown");
+                                       break;
+                               case VALIDATION_FAILED:
+                               case VALIDATION_SKIPPED:
+                                       DBG1(DBG_CFG, "certificate status is not available");
+                                       break;          
+                               default:
+                                       break;
+                       }
+               }
+       }
+       return TRUE;
+}
+
+/**
+ * credential_set_t implementation around a auth_info_t
+ */
+typedef struct auth_wrapper_t {
+       credential_set_t set;
+       auth_info_t *auth;
+} auth_wrapper_t;
+
+/**
+ * enumerator for auth_wrapper_t.create_cert_enumerator()
+ */
+typedef struct {
+       enumerator_t public;
+       enumerator_t *inner;
+       certificate_type_t cert;
+       key_type_t key;
+       identification_t *id;
+} auth_wrapper_enumerator_t;
+
+/**
+ * enumerate function for auth_wrapper_enumerator_t
+ */
+static bool auth_wrapper_enum_enumerate(auth_wrapper_enumerator_t *this,
+                                                                           certificate_t **cert)
+{
+       auth_item_t type;
+       certificate_t *current;
+       public_key_t *public;
+
+       while (this->inner->enumerate(this->inner, &type, &current))
+       {
+               if (type != AUTHN_SUBJECT_CERT && 
+                       type != AUTHN_IM_CERT)
+               {
+                       continue;
+               }
+
+               if (this->cert != CERT_ANY && this->cert != current->get_type(current))
+               {       /* CERT type requested, but does not match */
+                       continue;
+               }
+               public = current->get_public_key(current);
+               if (this->key != KEY_ANY && !public)
+               {       /* key type requested, but no public key */
+                       DESTROY_IF(public);
+                       continue;
+               }
+               if (this->key != KEY_ANY && public && this->key != public->get_type(public))
+               {       /* key type requested, but public key has another type */
+                       DESTROY_IF(public);
+                       continue;
+               }
+               DESTROY_IF(public);
+               if (this->id && !current->has_subject(current, this->id))
+               {       /* subject requested, but does not match */
+                       continue;
+               }
+               *cert = current;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * destroy function for auth_wrapper_enumerator_t
+ */
+static void auth_wrapper_enum_destroy(auth_wrapper_enumerator_t *this)
+{
+       this->inner->destroy(this->inner);
+       free(this);
+}
+
+/**
+ * implementation of auth_wrapper_t.set.create_cert_enumerator
+ */
+static enumerator_t *auth_wrapper_create_enumerator(auth_wrapper_t *this,
+                                                                               certificate_type_t cert, key_type_t key,
+                                                                               identification_t *id, bool trusted)
+{
+       auth_wrapper_enumerator_t *enumerator;
+       
+       if (trusted)
+       {
+               return NULL;
+       }
+       
+       enumerator = malloc_thing(auth_wrapper_enumerator_t);
+       enumerator->cert = cert;
+       enumerator->key = key;
+       enumerator->id = id;
+       enumerator->inner = this->auth->create_item_enumerator(this->auth);
+       enumerator->public.enumerate = (void*)auth_wrapper_enum_enumerate;
+       enumerator->public.destroy = (void*)auth_wrapper_enum_destroy;
+       return &enumerator->public;
+}
+
+/**
+ * create credential_set wrapper around auth_info_t
+ */
+static auth_wrapper_t *auth_wrapper_create(auth_info_t *auth)
+{
+       auth_wrapper_t *this = malloc_thing(auth_wrapper_t);
+       
+       this->auth = auth;
+       this->set.create_private_enumerator = (void*)return_null;
+       this->set.create_cert_enumerator = (void*)auth_wrapper_create_enumerator;
+       this->set.create_shared_enumerator = (void*)return_null;
+       this->set.create_cdp_enumerator = (void*)return_null;
+
+       return this;
+}
+
+/**
+ * Get a trusted certificate
+ */
+static certificate_t *get_trusted_cert(private_credential_manager_t *this,
+                                                                          key_type_t type, identification_t *id,
+                                                                          auth_info_t *auth, bool crl, bool ocsp)
+{
+       enumerator_t *enumerator;
+       auth_wrapper_t *wrapper;
+       certificate_t *subject, *issuer, *candidate;
+       public_key_t *public;
+       bool trusted = FALSE;
+       auth_info_t *auth1, *auth2;
+       u_int level = 0;
+       
+       this->mutex->lock(this->mutex);
+       wrapper = auth_wrapper_create(auth);
+       this->sets->insert_first(this->sets, wrapper);
+       
+       /* check if we have a trusted certificate for that peer */
+       auth1 = auth_info_create();
+       subject = get_cert(this, CERT_ANY, type, id, TRUE);
+       if (subject)
+       {
+               if (check_certificate(this, subject, NULL, crl, ocsp, auth1))
+               {
+                       public = subject->get_public_key(subject);
+                       if (public)
+                       {
+                               DBG2(DBG_CFG, "using trusted certificate %D",
+                                        subject->get_subject(subject));
+                               this->sets->remove(this->sets, wrapper, NULL);
+                               free(wrapper);
+                               this->mutex->unlock(this->mutex);
+                               auth->add_item(auth1, AUTHZ_SUBJECT_CERT, subject);
+                               public->destroy(public);
+                               auth->merge(auth, auth1);
+                               auth1->destroy(auth1);
+                               return subject;
+                       }
+               }
+               subject->destroy(subject);
+       }
+       auth1->destroy(auth1);
+       
+       /* check for an untrusted certificate */
+       auth1 = auth_info_create();
+       subject = get_cert(this, CERT_ANY, type, id, FALSE);
+       if (!subject)
+       {
+               DBG1(DBG_CFG, "no end entity certificate found for %D", id);
+       }
+       else
+       {
+               issuer = subject;
+               do
+               {
+                       /* look for a trusted certificate */
+                       auth2 = auth_info_create();
+                       enumerator = create_cert_enumerator(this, issuer->get_type(issuer), 
+                                                                       KEY_ANY, issuer->get_issuer(issuer), TRUE);
+                       while (enumerator->enumerate(enumerator, &candidate))
+                       {
+                               if (check_certificate(this, issuer, candidate, crl, ocsp,
+                                                                         issuer == subject ? auth2 : NULL) &&
+                                       check_certificate(this, candidate, NULL, crl, ocsp, NULL))
+                               {
+                                       DBG2(DBG_CFG, "using trusted root CA certificate %D",
+                                                candidate->get_subject(candidate));
+                                       issuer = candidate;
+                                       trusted = TRUE;
+                                       auth1->merge(auth1, auth2);
+                                       auth1->add_item(auth1, AUTHZ_CA_CERT, candidate);
+                                       break;
+                               }
+                       }
+                       enumerator->destroy(enumerator);
+                       auth2->destroy(auth2);
+                       if (trusted)
+                       {
+                               break;
+                       }
+                       
+                       /* no trusted certificate found, look for an untrusted */
+                       enumerator = create_cert_enumerator(this, issuer->get_type(issuer), 
+                                                                       KEY_ANY, issuer->get_issuer(issuer), FALSE);
+                       while (enumerator->enumerate(enumerator, &candidate))
+                       {
+                               auth2 = auth_info_create();
+                               if (check_certificate(this, issuer, candidate, crl, ocsp,
+                                                                         issuer == subject ? auth2 : NULL))
+                               {
+                                       if (issuer != subject)
+                                       {
+                                               DBG2(DBG_CFG, "using intermediate CA certificate %D",
+                                                        candidate->get_subject(candidate));
+                                               auth1->add_item(auth1, AUTHZ_IM_CERT, candidate);
+                                       }
+                                       else
+                                       {
+                                               DBG2(DBG_CFG, "using end entity certificate %D",
+                                                        candidate->get_subject(candidate));
+                                       }
+                                       issuer = candidate;
+                                       auth1->merge(auth1, auth2);
+                                       auth2->destroy(auth2);
+                                       /* check next level */
+                                       break;
+                               }
+                               auth2->destroy(auth2);
+                       }
+                       enumerator->destroy(enumerator);
+               }
+               while (++level < MAX_CA_LEVELS);
+               
+               if (!trusted)
+               {
+                       subject->destroy(subject);
+                       subject = NULL;
+               }
+       }
+       this->sets->remove(this->sets, wrapper, NULL);
+       free(wrapper);
+       this->mutex->unlock(this->mutex);
+       if (subject)
+       {
+               auth->add_item(auth, AUTHZ_SUBJECT_CERT, subject);
+               auth->merge(auth, auth1);
+               auth1->destroy(auth1);
+               return subject;
+       }
+       auth1->destroy(auth1);
+       return NULL;
+}
+
+/**
+ * Implementation of credential_manager_t.get_public.
+ */
+static public_key_t *get_public(private_credential_manager_t *this,
+                                                               key_type_t type, identification_t *id,
+                                                               auth_info_t *auth)
+{
+       public_key_t *public;
+       certificate_t *cert;
+       
+       cert = get_trusted_cert(this, type, id, auth, TRUE, TRUE);
+       if (cert)
+       {
+               public = cert->get_public_key(cert);
+               cert->destroy(cert);
+               return public;
+       }
+       return NULL;
+}
+
+/**
+ * Get the issuing certificate of a subject certificate
+ */
+static certificate_t *get_issuer_cert(private_credential_manager_t *this,
+                                                                         certificate_t *subject)
+{
+       enumerator_t *enumerator;
+       certificate_t *issuer = NULL, *candidate;
+       
+       enumerator = create_cert_enumerator(this, subject->get_type(subject), KEY_ANY, 
+                                                                               subject->get_issuer(subject), FALSE);
+       while (enumerator->enumerate(enumerator, &candidate))
+       {
+               if (subject->issued_by(subject, candidate, FALSE))
+               {
+                       issuer = candidate->get_ref(candidate);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return issuer;
+}
+
+/**
+ * Check if a certificate's keyid is contained in the auth helper
+ */
+static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
+{
+       enumerator_t *enumerator;
+       identification_t *value;
+       auth_item_t type;
+       bool found = FALSE;
+
+       enumerator = auth->create_item_enumerator(auth);
+       while (enumerator->enumerate(enumerator, &type, &value))
+       {
+               if (type == AUTHN_CA_CERT && cert->equals(cert, (certificate_t*)value))
+               {
+                       found = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
+/**
+ * Implementation of credential_manager_t.get_private.
+ */
+static private_key_t *get_private(private_credential_manager_t *this,
+                                                                 key_type_t type, identification_t *id,
+                                                                 auth_info_t *auth)
+{
+       enumerator_t *enumerator;
+       private_key_t *private;
+       public_key_t *public;
+       certificate_t *subject, *issuer, *candidate;
+       auth_info_t *cand_auth;
+       identification_t* keyid;
+       bool match = FALSE;
+       
+       /* check if this is a lookup by key ID, and do it if so */
+       if (id)
+       {
+               switch (id->get_type(id))
+               {
+                       case ID_PUBKEY_SHA1:
+                       case ID_PUBKEY_INFO_SHA1:
+                               return get_private_by_keyid(this, type, id);
+                       default:
+                               break;
+               }
+       }
+       
+       this->mutex->lock(this->mutex);
+       /* Check if peer has included its trust anchors.
+        * If not we fall back to our trust anchors */
+       if (!auth->get_item(auth, AUTHN_CA_CERT, (void**)&issuer))
+       {
+               enumerator = create_cert_enumerator(this, CERT_ANY, type, NULL, TRUE);
+               while (enumerator->enumerate(enumerator, &issuer))
+               {
+                       auth->add_item(auth, AUTHN_CA_CERT, issuer);
+               }
+               enumerator->destroy(enumerator);
+       }
+       DBG2(DBG_CFG, "finding private key with certificate the peer trusts");
+       
+       /* get all available end entity certificates for us... */
+       enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
+       while (enumerator->enumerate(enumerator, &subject))
+       {       /* ... check for public ... */
+               public = subject->get_public_key(subject);
+               if (public)
+               {       /* ... and private keys for that certificate, ... */
+                       /* TODO: check other keyid types? */
+                       keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+                       if (keyid)
+                       {
+                               private = get_private_by_keyid(this, type, keyid);
+                               if (private)
+                               {
+                                       u_int level = 0;
+                                       bool bad_path = FALSE;
+                                       issuer = NULL;
+                       
+                                       match = TRUE;
+                                       DBG2(DBG_CFG, "  checking end entity cert %D",
+                                                subject->get_subject(subject));
+                                       cand_auth = auth_info_create();
+                                       /* .. check for a trust-path up to a peer-trusted CA */
+                                       candidate = subject->get_ref(subject);
+                                       while (!auth_contains_cacert(auth, candidate))
+                                       {
+                                               cand_auth->add_item(cand_auth, subject == candidate ?
+                                                               AUTHZ_SUBJECT_CERT : AUTHZ_IM_CERT,     candidate);
+                                               issuer = get_issuer_cert(this, candidate);
+                                               /* check if we have an issuing certificate */
+                                               if (!issuer)
+                                               {
+                                                       DBG2(DBG_CFG, "    no issuer, checking next cert");
+                                                       bad_path = TRUE;
+                                                       break;
+                                               }
+                                               /* and it is not self-issued */
+                                               if (issuer->equals(issuer, candidate) ||
+                                                       level > MAX_CA_LEVELS)
+                                               {
+                                                       issuer->destroy(issuer);
+                                                       issuer = NULL;
+                                                       bad_path = TRUE;
+                                                       DBG2(DBG_CFG, "    cert is self-signed, skipped");
+                                                       break;
+                                               }
+                                               DBG2(DBG_CFG, "    checking issuer cert %D",
+                                                        issuer->get_subject(issuer));
+                                               candidate->destroy(candidate);
+                                               candidate = issuer;
+                                               level++;
+                                       }
+                                       if (bad_path)
+                                       {       /* no issuer cert found peer trusts, try another path */
+                                               cand_auth->destroy(cand_auth);
+                                               private->destroy(private);
+                                               public->destroy(public);
+                                               continue;
+                                       }
+                                       if (issuer)
+                                       {
+                                               DBG2(DBG_CFG, "  peer trusts issuer %D",
+                                                        issuer->get_subject(issuer));
+                                       }
+                                       else
+                                       {
+                                               candidate->destroy(candidate);
+                                       }
+                                       auth->merge(auth, cand_auth);
+                                       cand_auth->destroy(cand_auth);
+                                       DESTROY_IF(issuer);
+                                       public->destroy(public);
+                                       enumerator->destroy(enumerator);
+                                       this->mutex->unlock(this->mutex);
+                                       return private;
+                               }
+                       }
+                       public->destroy(public);
+               }
+       }
+       this->mutex->unlock(this->mutex);
+       if (match)
+       {
+               DBG1(DBG_CFG, "found a private key/cert for %D, but none which the "
+                        "peer trusts", id);
+       }
+       else
+       {
+               DBG1(DBG_CFG, "no private key found for %D", id);
+       }
+       /* no trusted path found, unable to sign */
+       return NULL;
+}
+
+/**
+ * Implementation of credential_manager_t.add_set.
+ */
+static void add_set(private_credential_manager_t *this,
+                                                          credential_set_t *set)
+{
+       this->mutex->lock(this->mutex);
+       this->sets->insert_last(this->sets, set);
+       this->mutex->unlock(this->mutex);
+}
+/**
+ * Implementation of credential_manager_t.remove_set.
+ */
+static void remove_set(private_credential_manager_t *this, credential_set_t *set)
+{
+       this->mutex->lock(this->mutex);
+       this->sets->remove(this->sets, set, NULL);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of credential_manager_t.destroy
+ */
+static void destroy(private_credential_manager_t *this)
+{
+       this->sets->destroy(this->sets);
+       this->mutex->destroy(this->mutex);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+credential_manager_t *credential_manager_create()
+{
+       private_credential_manager_t *this = malloc_thing(private_credential_manager_t);
+       
+       this->public.create_cert_enumerator = (enumerator_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *id,bool))create_cert_enumerator;
+       this->public.create_shared_enumerator = (enumerator_t *(*)(credential_manager_t *this, shared_key_type_t type,identification_t *me, identification_t *other))create_shared_enumerator;
+       this->public.create_cdp_enumerator = (enumerator_t *(*)(credential_manager_t*, credential_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.get_public = (public_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_info_t*))get_public;
+       this->public.add_set = (void(*)(credential_manager_t*, credential_set_t *set))add_set;
+       this->public.remove_set = (void(*)(credential_manager_t*, credential_set_t *set))remove_set;
+       this->public.destroy = (void(*)(credential_manager_t*))destroy;
+       
+       this->sets = linked_list_create();
+       this->mutex = mutex_create(MUTEX_RECURSIVE);
+       
+       return &this->public;
+}
+
diff --git a/src/charon/credentials/credential_manager.h b/src/charon/credentials/credential_manager.h
new file mode 100644 (file)
index 0000000..816b902
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2007-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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup credential_manager credential_manager
+ * @{ @ingroup ccredentials
+ */
+
+#ifndef CREDENTIAL_MANAGER_H_
+#define CREDENTIAL_MANAGER_H_
+
+#include <utils/identification.h>
+#include <utils/enumerator.h>
+#include <credentials/auth_info.h>
+#include <credentials/credential_set.h>
+#include <credentials/keys/private_key.h>
+#include <credentials/keys/shared_key.h>
+#include <credentials/certificates/certificate.h>
+
+typedef struct credential_manager_t credential_manager_t;
+
+/**
+ * Manages credentials using credential_sets.
+ *
+ * The credential manager is the entry point of the credential framework. It
+ * uses so called "sets" to access credentials in a modular fashion, these
+ * are implemented through the credential_set_t interface. 
+ * The manager additionally does trust chain verification and trust status
+ * chaching. A set may call the managers methods if it needs credentials itself,
+ * the manager uses recursive locking.
+ * 
+ * @verbatim
+
+  +-------+        +----------------+
+  |   A   |        |                |          +------------------+
+  |   u   | -----> |                | ------>  |  +------------------+
+  |   t   |        |   credential-  |          |  |  +------------------+
+  |   h   | -----> |     manager    | ------>  +--|  |   credential-    | => IPC
+  |   e   |        |                |             +--|       sets       |
+  |   n   |   +--> |                | ------>        +------------------+
+  |   t   |   |    |                |                        |
+  |   i   |   |    |                |                        |
+  |   c   |   |    +----------------+                        |
+  |   a   |   |                                              |
+  |   t   |   +----------------------------------------------+
+  |   o   |                    may be recursive
+  |   r   |
+  +-------+
+    
+   @endverbatim                                       
+ *
+ * Synchronization is done completely in the manager, so the sets don't have
+ * to worry about it. The locking mechanism is reentrant save, so sets can
+ * call the manager.
+ */
+struct credential_manager_t {
+       
+       /**
+        * Create an enumerator over all certificates.
+        *
+        * @param cert          kind of certificate
+        * @param key           kind of key in certificate
+        * @param id            subject this certificate belongs to
+        * @param trusted       TRUE to list trusted certificates only
+        * @return                      enumerator over the certificates
+        */
+       enumerator_t *(*create_cert_enumerator)(credential_manager_t *this,
+                                                               certificate_type_t cert, key_type_t key,
+                                                               identification_t *id, bool trusted);
+       /**
+        * Create an enumerator over all shared keys.
+        *
+        * The enumerator enumerates over:
+        *  shared_key_t*, id_match_t me, id_match_t other
+        * But must accepts values for the id_matches.
+        *
+        * @param type          kind of requested shared key
+        * @param first         first subject between key is shared
+        * @param second        second subject between key is shared
+        * @return                      enumerator over shared keys
+        */
+       enumerator_t *(*create_shared_enumerator)(credential_manager_t *this, 
+                                                               shared_key_type_t type,
+                                                               identification_t *first, identification_t *second);
+       /**
+        * Create an enumerator over all Certificate Distribution Points.
+        *
+        * @param type          kind of certificate the point distributes
+        * @param id            identification of the distributed certificate
+        * @return                      enumerator of CDPs as char*
+        */
+       enumerator_t *(*create_cdp_enumerator)(credential_manager_t *this,
+                                                               credential_type_t type, identification_t *id);
+       /**
+        * Get a trusted or untrusted certificate.
+        *
+        * @param cert          kind of certificate
+        * @param key           kind of key in certificate
+        * @param id            subject this certificate belongs to
+        * @param trusted       TRUE to get a trusted certificate only
+        * @return                      certificate, if found, NULL otherwise
+        */
+       certificate_t *(*get_cert)(credential_manager_t *this,
+                                                          certificate_type_t cert, key_type_t key,
+                                                          identification_t *id, bool trusted);
+       /**
+        * Get the best matching shared key for two IDs.
+        *
+        * @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,
+                                                               identification_t *me, identification_t *other);
+       /**
+        * Get a private key to create a signature.
+        *
+        * The get_private() method gets a secret private key identified by either
+        * the keyid itself or an id the key belongs to. 
+        * The auth parameter contains additional information, such as receipients
+        * trusted CA certs. Auth gets filled with subject and CA certificates
+        * needed to validate a created signature.
+        *
+        * @param type          type of the key to get
+        * @param id            identification the key belongs to
+        * @param auth          auth_info helper, 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);
+       /**
+        * Get a public key to verify a signature.
+        *
+        * The get_public() method gets a trusted public key to verify a signature
+        * of id. The auth parameter contains additional authentication infos,
+        * e.g. peer and intermediate certificates.
+        *
+        * @param type          type of key to get
+        * @param id            identification the key belongs to
+        * @param auth          auth_info helper, including certificates to verify key
+        * @return                      public_key_t, NULL if none found
+        */
+       public_key_t* (*get_public)(credential_manager_t *this, key_type_t type,
+                                                               identification_t *id, auth_info_t *auth);
+       
+       /**
+        * Register a credential set to the manager.
+        *
+        * @param set           set to register
+        */
+       void (*add_set)(credential_manager_t *this, credential_set_t *set);
+       
+       /**
+        * Unregister a credential set from the manager.
+        *
+        * @param set           set to unregister
+        */
+       void (*remove_set)(credential_manager_t *this, credential_set_t *set);
+       
+       /**
+     * Destroy a credential_manager instance.
+     */
+    void (*destroy)(credential_manager_t *this);
+};
+
+/**
+ * Create a credential_manager instance.
+ */
+credential_manager_t *credential_manager_create();
+
+#endif /* CREDENTIAL_MANAGER_H_ @} */
diff --git a/src/charon/credentials/credential_set.h b/src/charon/credentials/credential_set.h
new file mode 100644 (file)
index 0000000..a4e891a
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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$
+ */
+
+/**
+ * @defgroup credential_set credential_set
+ * @{ @ingroup ccredentials
+ */
+
+#ifndef CREDENTIAL_SET_H_
+#define CREDENTIAL_SET_H_
+
+#include <credentials/keys/public_key.h>
+#include <credentials/keys/shared_key.h>
+#include <credentials/certificates/certificate.h>
+
+typedef struct credential_set_t credential_set_t;
+
+/**
+ * A set of credentials.
+ *
+ * Contains private keys, shared keys and different kinds of certificates.
+ * Enumerators are used because queries might return multiple matches.
+ * Filter parameters restrict enumeration over specific items only.
+ * See credential_manager_t for an overview of the credential framework.
+ */
+struct credential_set_t {
+       
+       /**
+        * Create an enumerator over private keys (private_key_t).
+        *
+        * The id is either a key identifier of the requested key, or an identity
+        * of the key owner. 
+        *
+        * @param type          type of requested private key
+        * @param id            key identifier/owner
+        * @return                      enumerator over private_key_t's.
+        */
+       enumerator_t *(*create_private_enumerator)(credential_set_t *this,
+                                               key_type_t type, identification_t *id);
+       /**
+        * Create an enumerator over certificates (certificate_t).
+        *
+        * @param cert          kind of certificate
+        * @param key           kind of key in certificate
+        * @param id            identity (subject) this certificate belongs to
+        * @param trusted       whether the certificate must be trustworthy
+        * @return                      enumerator as described above
+        */
+       enumerator_t *(*create_cert_enumerator)(credential_set_t *this,
+                                               certificate_type_t cert, key_type_t key,
+                                               identification_t *id, bool trusted);
+       /**
+        * Create an enumerator over shared keys (shared_key_t).
+        *
+        * The enumerator enumerates over:
+        *  shared_key_t*, id_match_t me, id_match_t other
+        * But must accept NULL values for the id_matches.
+        *
+        * @param type          kind of requested shared key
+        * @param me            own identity
+        * @param other         other identity who owns that secret
+        * @return                      enumerator as described above
+        */
+       enumerator_t *(*create_shared_enumerator)(credential_set_t *this, 
+                                               shared_key_type_t type,
+                                               identification_t *me, identification_t *other);
+       
+       /**
+        * Create an enumerator over certificate distribution points.
+        *
+        * @param type          type of the certificate to get a CDP
+        * @param id            identification of the distributed certificate
+        * @return                      an enumerator over CDPs as char*
+        */
+       enumerator_t *(*create_cdp_enumerator)(credential_set_t *this,
+                                               certificate_type_t type, identification_t *id); 
+};
+
+#endif /* CREDENTIAL_SET_H_ @} */
index ee97104244756ce908f8a64d76f397a4e908a20b..122c5cfccfd31d0b9529a22dcbc085913dcb4fdf 100644 (file)
@@ -1,13 +1,7 @@
-/**
- * @file daemon.c
- * 
- * @brief Implementation of daemon_t and main of IKEv2-Daemon.
- * 
- */
-
-/* Copyright (C) 2006-2007 Tobias Brunner
+/* 
+ * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
 #include "daemon.h"
 
 #include <library.h>
-#include <crypto/ca.h>
-#include <utils/fetcher.h>
-#include <config/credentials/local_credential_store.h>
-#include <config/backends/local_backend.h>
-#include <sa/authenticators/eap/eap_method.h>
+#include <credentials/credential_manager.h>
+#include <config/backend_manager.h>
+#include <config/traffic_selector.h>
 
 /* on some distros, a capset definition is missing */
 #ifdef NO_CAPSET_DEFINED
@@ -100,6 +92,12 @@ static void dbg_bus(int level, char *fmt, ...)
        charon->bus->vsignal(charon->bus, DBG_LIB, level, fmt, args);
        va_end(args);
 }
+/**
+ * Logging hook for library logs before logging facility initiated
+ */
+static void dbg_silent(int level, char *fmt, ...)
+{
+}
 
 /**
  * Logging hook for library logs, using stderr output
@@ -171,12 +169,17 @@ static void run(private_daemon_t *this)
 static void destroy(private_daemon_t *this)
 {
        /* terminate all idle threads */
-       this->public.processor->set_threads(this->public.processor, 0);
+       if (this->public.processor)
+       {
+               this->public.processor->set_threads(this->public.processor, 0);
+       }
        /* close all IKE_SAs */
+       DESTROY_IF(this->public.plugins);
        DESTROY_IF(this->public.ike_sa_manager);
        DESTROY_IF(this->public.kernel_interface);
        DESTROY_IF(this->public.scheduler);
-       DESTROY_IF(this->public.interfaces);
+       DESTROY_IF(this->public.controller);
+       DESTROY_IF(this->public.eap);
 #ifdef P2P     
        DESTROY_IF(this->public.connect_manager);
        DESTROY_IF(this->public.mediation_manager);
@@ -323,29 +326,38 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
 #endif /* INTEGRITY_TEST */
        
        this->public.ike_sa_manager = ike_sa_manager_create();
+       if (this->public.ike_sa_manager == NULL)
+       {
+               return FALSE;
+       }
        this->public.processor = processor_create();
        this->public.scheduler = scheduler_create();
 
        /* load secrets, ca certificates and crls */
-       this->public.credentials = (credential_store_t*)local_credential_store_create();
-       this->public.credentials->load_ca_certificates(this->public.credentials);
-       this->public.credentials->load_aa_certificates(this->public.credentials);
-       this->public.credentials->load_attr_certificates(this->public.credentials);
-       this->public.credentials->load_ocsp_certificates(this->public.credentials);
-       this->public.credentials->load_crls(this->public.credentials);
-       this->public.credentials->load_secrets(this->public.credentials, FALSE);
-       
-       this->public.interfaces = interface_manager_create();
+       this->public.credentials = credential_manager_create();
+       this->public.controller = controller_create();
+       this->public.eap = eap_manager_create();
        this->public.backends = backend_manager_create();
+       this->public.plugins = plugin_loader_create();
        this->public.kernel_interface = kernel_interface_create();
        this->public.socket = socket_create();
        this->public.sender = sender_create();
        this->public.receiver = receiver_create();
+       if (this->public.receiver == NULL)
+       {
+               return FALSE;
+       }
        
 #ifdef P2P
        this->public.connect_manager = connect_manager_create();
+       if (this->public.connect_manager == NULL)
+       {
+               return FALSE;
+       }
        this->public.mediation_manager = mediation_manager_create();
 #endif /* P2P */
+
+       this->public.plugins->load(this->public.plugins, IPSEC_PLUGINDIR, "libcharon-");
        
        return TRUE;
 }
@@ -401,7 +413,9 @@ private_daemon_t *daemon_create(void)
        this->public.scheduler = NULL;
        this->public.kernel_interface = NULL;
        this->public.processor = NULL;
-       this->public.interfaces = NULL;
+       this->public.controller = NULL;
+       this->public.eap = NULL;
+       this->public.plugins = NULL;
        this->public.bus = NULL;
        this->public.outlog = NULL;
        this->public.syslog = NULL;
@@ -443,7 +457,6 @@ static void usage(const char *msg)
                                        "         [--strictcrlpolicy]\n"
                                        "         [--cachecrls]\n"
                                        "         [--crlcheckinterval <interval>]\n"
-                                       "         [--eapdir <dir>]\n"
                                        "         [--use-syslog]\n"
                                        "         [--debug-<type> <level>]\n"
                                        "           <type>:  log context type (dmn|mgr|ike|chd|job|cfg|knl|net|enc|lib)\n"
@@ -460,10 +473,8 @@ static void usage(const char *msg)
 int main(int argc, char *argv[])
 {
        u_int crl_check_interval = 0;
-       strict_t strict_crl_policy = STRICT_NO;
        bool cache_crls = FALSE;
        bool use_syslog = FALSE;
-       char *eapdir = IPSEC_EAPDIR;
 
        private_daemon_t *private_charon;
        FILE *pid_file;
@@ -471,6 +482,14 @@ int main(int argc, char *argv[])
        level_t levels[DBG_MAX];
        int signal;
        
+       /* silence the library during initialization, as we have no bus yet */
+       dbg = dbg_silent;
+       
+       /* initialize library */
+       library_init(IPSEC_DIR "/strongswan.conf");
+       lib->plugins->load(lib->plugins, IPSEC_PLUGINDIR, "libstrongswan-");
+       lib->printf_hook->add_handler(lib->printf_hook, 'R',
+                                                                 traffic_selector_get_printf_hooks());
        private_charon = daemon_create();
        charon = (daemon_t*)private_charon;
        
@@ -491,10 +510,8 @@ int main(int argc, char *argv[])
                        { "help", no_argument, NULL, 'h' },
                        { "version", no_argument, NULL, 'v' },
                        { "use-syslog", no_argument, NULL, 'l' },
-                       { "strictcrlpolicy", required_argument, NULL, 'r' },
                        { "cachecrls", no_argument, NULL, 'C' },
                        { "crlcheckinterval", required_argument, NULL, 'x' },
-                       { "eapdir", required_argument, NULL, 'e' },
                        /* TODO: handle "debug-all" */
                        { "debug-dmn", required_argument, &signal, DBG_DMN },
                        { "debug-mgr", required_argument, &signal, DBG_MGR },
@@ -523,18 +540,12 @@ int main(int argc, char *argv[])
                        case 'l':
                                use_syslog = TRUE;
                                continue;
-                       case 'r':
-                               strict_crl_policy = atoi(optarg);
-                               continue;
                        case 'C':
                                cache_crls = TRUE;
                                continue;
                        case 'x':
                                crl_check_interval = atoi(optarg);
                                continue;
-                       case 'e':
-                               eapdir = optarg;
-                               continue;
                        case 0:
                                /* option is in signal */
                                levels[signal] = atoi(optarg);
@@ -554,14 +565,6 @@ int main(int argc, char *argv[])
                exit(-1);
        }
 
-       /* initialize fetcher_t class */
-       fetcher_initialize();
-       /* load pluggable EAP modules */
-       eap_method_load(eapdir);
-       
-       /* set strict_crl_policy, cache_crls and crl_check_interval options */
-       ca_info_set_options(strict_crl_policy, cache_crls, crl_check_interval);
-
        /* check/setup PID file */
        if (stat(PID_FILE, &stb) == 0)
        {
@@ -586,12 +589,12 @@ int main(int argc, char *argv[])
        /* run daemon */
        run(private_charon);
        
-       eap_method_unload();
-       fetcher_finalize();
        /* normal termination, cleanup and exit */
        destroy(private_charon);
        unlink(PID_FILE);
        
+       library_deinit();
+       
        return 0;
 }
 
index 33c63091d382ce89d23f04609c4c412ea44b62a5..d989c0bba854a6a0a9854c024d746b722d2de773 100644 (file)
@@ -1,14 +1,7 @@
-/**
- * @file daemon.h
- *
- * @brief Interface of daemon_t.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * WITHOUT ANY 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 DAEMON_H_
-#define DAEMON_H_
-
-typedef struct daemon_t daemon_t;
-
-#include <credential_store.h>
-
-#include <network/sender.h>
-#include <network/receiver.h>
-#include <network/socket.h>
-#include <processing/scheduler.h>
-#include <processing/processor.h>
-#include <kernel/kernel_interface.h>
-#include <control/interface_manager.h>
-#include <bus/bus.h>
-#include <bus/listeners/file_logger.h>
-#include <bus/listeners/sys_logger.h>
-#include <sa/ike_sa_manager.h>
-#include <config/backend_manager.h>
-
-#ifdef P2P
-#include <sa/connect_manager.h>
-#include <sa/mediation_manager.h>
-#endif /* P2P */
-
 /**
  * @defgroup charon charon
  *
- * @brief IKEv2 keying daemon.
- *
- * All IKEv2 stuff is handled in charon. It uses a newer and more flexible
- * architecture than pluto. Charon uses a thread-pool (called processor),
- * which allows parallel execution SA-management. All threads originate
- * from the processor. Work is delegated to the processor by queueing jobs
- * to it.
-   @verbatim                                             
-                          
-      +--------+   +-------+   +--------+       +-----------+    +-----------+
-      | Stroke |   |  XML  |   |  DBUS  |       |   Local   |    |   SQLite  |
-      +--------+   +-------+   +--------+       +-----------+    +-----------+
-          |            |           |                  |                |
-      +---------------------------------+       +----------------------------+
-      |             Interfaces          |       |          Backends          |
-      +---------------------------------+       +----------------------------+  
-                                                                              
-                                                                                
-       +------------+    +-----------+        +------+            +----------+
-       |  receiver  |    |           |        |      |  +------+  | CHILD_SA |
-       +----+-------+    | Scheduler |        | IKE- |  | IKE- |--+----------+
-            |            |           |        | SA   |--| SA   |  | CHILD_SA |
-    +-------+--+         +-----------+        |      |  +------+  +----------+
- <->|  socket  |               |              | Man- |
-    +-------+--+         +-----------+        | ager |  +------+  +----------+
-            |            |           |        |      |  | IKE- |--| CHILD_SA |
-       +----+-------+    | Processor |--------|      |--| SA   |  +----------+
-       |   sender   |    |           |        |      |  +------+                  
-       +------------+    +-----------+        +------+                   
-                                                                                 
-                                                                                
-      +---------------------------------+       +----------------------------+
-      |               Bus               |       |      Kernel Interface      |
-      +---------------------------------+       +----------------------------+                                                                 
-             |                    |                           |
-      +-------------+     +-------------+                     V
-      | File-Logger |     |  Sys-Logger |                  //////
-      +-------------+     +-------------+                       
-
-
-   @endverbatim
- * The scheduler is responsible to execute timed events. Jobs may be queued to 
- * the scheduler to get executed at a defined time (e.g. rekeying). The scheduler
- * does not execute the jobs itself, it queues them to the processor.
- * 
- * The IKE_SA manager managers all IKE_SA. It further handles the synchronization:
- * Each IKE_SA must be checked out strictly and checked in again after use. The 
- * manager guarantees that only one thread may check out a single IKE_SA. This allows
- * us to write the (complex) IKE_SAs routines non-threadsave.
- * The IKE_SA contain the state and the logic of each IKE_SA and handle the messages.
- * 
- * The CHILD_SA contains state about a IPsec security association and manages them. 
- * An IKE_SA may have multiple CHILD_SAs. Communication to the kernel takes place
- * here through the kernel interface.
- * 
- * The kernel interface installs IPsec security associations, policies routes and 
- * virtual addresses. It further provides methods to enumerate interfaces and may notify
- * the daemon about state changes at lower layers.
- * 
- * The bus receives signals from the different threads and relais them to interested 
- * listeners. Debugging signals, but also important state changes or error messages are
- * sent over the bus. 
- * It's listeners are not only for logging, but also to track the state of an IKE_SA.
- * 
- * The interface manager loads pluggable controlling interfaces. These are written to control
- * the daemon from external inputs (e.g. initiate IKE_SA, close IKE_SA, ...). The interface
- * manager further provides a simple API to establish these tasks.
- * Backends are pluggable modules which provide configuration. They have to implement an API
- * which the daemon core uses to get configuration.
- */
-
-/**
  * @defgroup bus bus
- *
- * Signaling bus and its listeners.
- *
  * @ingroup charon
- */
-
-/**
- * @defgroup config config
- *
- * Classes implementing configuration related things.
+ * 
+ * @defgroup listeners listeners
+ * @ingroup bus
  *
+ * @defgroup config config
  * @ingroup charon
- */
-
-/**
- * @defgroup backends backends
- *
- * Classes implementing configuration backends.
- *
- * @ingroup config
- */
-
-/**
- * @defgroup credentials credentials
- *
- * Trust chain verification and certificate store.
  *
- * @ingroup config
- */
-
-/**
  * @defgroup control control
- *
- * Handling of loadable control interface modules.
- *
  * @ingroup charon
- */
-
-/**
- * @defgroup interfaces interfaces
  *
- * Classes which control the daemon using IPC mechanisms.
+ * @defgroup ccredentials credentials
+ * @ingroup charon
  *
- * @ingroup control
- */
-
-/**
  * @defgroup encoding encoding
- *
- * Classes used to encode and decode IKEv2 messages.
- *
  * @ingroup charon
- */
-
- /**
- * @defgroup payloads payloads
- *
- * Classes representing specific IKEv2 payloads.
  *
+ * @defgroup payloads payloads
  * @ingroup encoding
- */
-
-/**
- * @defgroup kernel kernel
- *
- * Classes to configure and query the kernel.
  *
+ * @defgroup kernel kernel
  * @ingroup charon
- */
-
-/**
- * @defgroup network network
- *
- * Classes for sending and receiving UDP packets over the network.
  *
+ * @defgroup network network
  * @ingroup charon
- */
-
-/**
- * @defgroup processing processing
- *
- * Queueing, scheduling and processing of jobs
  *
+ * @defgroup cplugins plugins
  * @ingroup charon
- */
-
-/**
- * @defgroup jobs jobs
  *
- * Jobs to queue, schedule and process.
+ * @defgroup processing processing
+ * @ingroup charon
  *
+ * @defgroup jobs jobs
  * @ingroup processing
- */
-
-/**
- * @defgroup sa sa
- *
- * Security associations for IKE and IPSec, and its helper classes.
  *
+ * @defgroup sa sa
  * @ingroup charon
- */
-
-/**
+ *
  * @defgroup authenticators authenticators
+ * @ingroup sa
  *
- * Authenticator classes to prove identity of a peer.
+ * @defgroup eap eap
+ * @ingroup authenticators
  *
+ * @defgroup tasks tasks
  * @ingroup sa
- */
-
-/**
- * @defgroup eap eap
  *
- * EAP module loader, interface and it's implementations.
+ * @addtogroup charon
+ * @{
  *
- * @ingroup authenticators
- */
-/**
- * @defgroup tasks tasks
+ * IKEv2 keying daemon.
  *
- * Tasks process and build message payloads. They are used to create
- * and process multiple exchanges.
+ * All IKEv2 stuff is handled in charon. It uses a newer and more flexible
+ * architecture than pluto. Charon uses a thread-pool (called processor),
+ * which allows parallel execution SA-management. All threads originate
+ * from the processor. Work is delegated to the processor by queueing jobs
+ * to it.
+   @verbatim
+   
+      +---------------------------------+       +----------------------------+
+      |           controller            |       |          config            |
+      +---------------------------------+       +----------------------------+  
+               |      |      |                           ^     ^    ^           
+               V      V      V                           |     |    |           
+                                                                                
+       +----------+  +-----------+   +------+            +----------+    +----+
+       | receiver |  |           |   |      |  +------+  | CHILD_SA |    | K  |
+       +---+------+  | Scheduler |   | IKE- |  | IKE- |--+----------+    | e  |
+           |         |           |   | SA   |--| SA   |  | CHILD_SA |    | r  |
+    +------+---+     +-----------+   |      |  +------+  +----------+    | n  |
+ <->|  socket  |           |         | Man- |                            | e  |
+    +------+---+     +-----------+   | ager |  +------+  +----------+    | l  |
+           |         |           |   |      |  | IKE- |--| CHILD_SA |    | -  |
+       +---+------+  | Processor |---|      |--| SA   |  +----------+    | I  |
+       |  sender  |  |           |   |      |  +------+                  | f  |    
+       +----------+  +-----------+   +------+                            +----+
+                                                                                
+               |      |      |                        |      |      |           
+               V      V      V                        V      V      V           
+      +---------------------------------+       +----------------------------+  
+      |               Bus               |       |         credentials        |  
+      +---------------------------------+       +----------------------------+                                                              
+
+   @endverbatim
+ * The scheduler is responsible to execute timed events. Jobs may be queued to 
+ * the scheduler to get executed at a defined time (e.g. rekeying). The 
+ * scheduler does not execute the jobs itself, it queues them to the processor.
+ * 
+ * The IKE_SA manager managers all IKE_SA. It further handles the 
+ * synchronization:
+ * Each IKE_SA must be checked out strictly and checked in again after use. The 
+ * manager guarantees that only one thread may check out a single IKE_SA. This 
+ * allows us to write the (complex) IKE_SAs routines non-threadsave.
+ * The IKE_SA contain the state and the logic of each IKE_SA and handle the 
+ * messages.
+ * 
+ * The CHILD_SA contains state about a IPsec security association and manages
+ * them. An IKE_SA may have multiple CHILD_SAs. Communication to the kernel 
+ * takes place here through the kernel interface.
+ * 
+ * The kernel interface installs IPsec security associations, policies, routes
+ * and virtual addresses. It further provides methods to enumerate interfaces 
+ * and may notify the daemon about state changes at lower layers.
+ * 
+ * The bus receives signals from the different threads and relais them to interested 
+ * listeners. Debugging signals, but also important state changes or error 
+ * messages are sent over the bus. 
+ * It's listeners are not only for logging, but also to track the state of an
+ * IKE_SA.
  *
- * @ingroup sa
+ * The controller, credential_manager, bus and backend_manager (config) are 
+ * places where a plugin ca register itself to privide information or observe
+ * and control the daemon.
  */
 
+#ifndef DAEMON_H_
+#define DAEMON_H_
+
+typedef struct daemon_t daemon_t;
+
+#include <network/sender.h>
+#include <network/receiver.h>
+#include <network/socket.h>
+#include <processing/scheduler.h>
+#include <processing/processor.h>
+#include <kernel/kernel_interface.h>
+#include <control/controller.h>
+#include <bus/bus.h>
+#include <bus/listeners/file_logger.h>
+#include <bus/listeners/sys_logger.h>
+#include <sa/ike_sa_manager.h>
+#include <config/backend_manager.h>
+#include <credentials/credential_manager.h>
+#include <sa/authenticators/eap/eap_manager.h>
+#include <plugins/plugin_loader.h>
+
+#ifdef P2P
+#include <sa/connect_manager.h>
+#include <sa/mediation_manager.h>
+#endif /* P2P */
+
 /**
  * Name of the daemon.
- *
- * @ingroup charon
  */
 #define DAEMON_NAME "charon"
 
 /**
- * @brief Number of threads in the thread pool.
- * 
- * @ingroup charon
+ * Number of threads in the thread pool.
  */
 #define WORKER_THREADS 16
 
 /**
  * UDP Port on which the daemon will listen for incoming traffic.
- * 
- * @ingroup charon
  */
 #define IKEV2_UDP_PORT 500
 
 /**
  * UDP Port to which the daemon will float to if NAT is detected.
- *
- * @ingroup charon
  */
 #define IKEV2_NATT_PORT 4500
 
 /**
  * PID file, in which charon stores its process id
- * 
- * @ingroup charon
  */
 #define PID_FILE IPSEC_PIDDIR "/charon.pid"
 
-/**
- * Configuration directory
- * 
- * @ingroup charon
- */
-#define CONFIG_DIR IPSEC_CONFDIR
-
-/**
- * Directory of IPsec relevant files
- * 
- * @ingroup charon
- */
-#define IPSEC_D_DIR CONFIG_DIR "/ipsec.d"
 
 /**
- * Default directory for private keys
- * 
- * @ingroup charon
- */
-#define PRIVATE_KEY_DIR IPSEC_D_DIR "/private"
-
-/**
- * Default directory for end entity certificates
- * 
- * @ingroup charon
- */
-#define CERTIFICATE_DIR IPSEC_D_DIR "/certs"
-
-/**
- * Default directory for trusted Certification Authority certificates
- * 
- * @ingroup charon
- */
-#define CA_CERTIFICATE_DIR IPSEC_D_DIR "/cacerts"
-
-/**
- * Default directory for Authorization Authority certificates
- * 
- * @ingroup charon
- */
-#define AA_CERTIFICATE_DIR IPSEC_D_DIR "/aacerts"
-
-/**
- * Default directory for Attribute certificates
- * 
- * @ingroup charon
- */
-#define ATTR_CERTIFICATE_DIR IPSEC_D_DIR "/acerts"
-
-/**
- * Default directory for OCSP signing certificates
- * 
- * @ingroup charon
- */
-#define OCSP_CERTIFICATE_DIR IPSEC_D_DIR "/ocspcerts"
-
-/**
- * Default directory for CRLs
- * 
- * @ingroup charon
- */
-#define CRL_DIR IPSEC_D_DIR "/crls"
-
-/**
- * Secrets files
- * 
- * @ingroup charon
- */
-#define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
-
-/**
- * @brief Main class of daemon, contains some globals.
- *
- * @ingroup charon
+ * Main class of daemon, contains some globals.
  */
 struct daemon_t {
        
@@ -379,9 +210,9 @@ struct daemon_t {
        backend_manager_t *backends;
        
        /**
-        * A credential_store_t instance.
+        * Manager for the credential backends
         */
-       credential_store_t *credentials;
+       credential_manager_t *credentials;
        
        /**
         * The Sender-Thread.
@@ -408,6 +239,11 @@ struct daemon_t {
         */
        bus_t *bus;
        
+       /**
+        * plugin loader
+        */
+       plugin_loader_t *plugins;
+       
        /**
         * A bus listener logging to stdout
         */
@@ -429,9 +265,14 @@ struct daemon_t {
        kernel_interface_t *kernel_interface;
        
        /**
-        * Interfaces for IPC
+        * Controller to control the daemon
+        */
+       controller_t *controller;
+       
+       /**
+        * EAP manager to maintain registered EAP methods
         */
-       interface_manager_t *interfaces;
+       eap_manager_t *eap;
        
 #ifdef P2P
        /**
@@ -446,9 +287,8 @@ struct daemon_t {
 #endif /* P2P */
        
        /**
-        * @brief Shut down the daemon.
+        * Shut down the daemon.
         * 
-        * @param this                  the daemon to kill
         * @param reason                describtion why it will be killed
         */
        void (*kill) (daemon_t *this, char *reason);
@@ -459,4 +299,4 @@ struct daemon_t {
  */
 extern daemon_t *charon;
 
-#endif /*DAEMON_H_*/
+#endif /*DAEMON_H_ @} */
index efa845bb38c6446104a50e34dc4c2d4d4499b2b5..79aedc259472c4aa2356311f45cff69d356cb1f8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file generator.c
- *
- * @brief Implementation of generator_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
index 8eff957cc73c9a8a6988d059f0bf88d37cb810b8..5cc7100708054cd47256109cb367ccddfb6ab4e8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file generator.h
- *
- * @brief Interface of generator_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 generator generator
+ * @{ @ingroup encoding
  */
 
 #ifndef GENERATOR_H_
@@ -33,21 +33,17 @@ typedef struct generator_t generator_t;
 /**
  * Generating is done in a data buffer.
  * This is thehe start size of this buffer in bytes.
- *
- * @ingroup enconding
  */
 #define GENERATOR_DATA_BUFFER_SIZE 500
 
 /**
  * Number of bytes to increase the buffer, if it is to small.
- *
- * @ingroup enconding
  */
 #define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500
 
 
 /**
- * @brief A generator_t class used to generate IKEv2 payloads.
+ * A generator_t class used to generate IKEv2 payloads.
  *
  * After creation, multiple payloads can be generated with the generate_payload
  * method. The generated bytes are appended. After all payloads are added, 
@@ -56,47 +52,36 @@ typedef struct generator_t generator_t;
  * The generater uses a set of encoding rules, which it can get from
  * the supplied payload. With this rules, the generater can generate
  * the payload and all substructures automatically.
- * 
- * @b Constructor:
- * - generator_create()
- * 
- * @ingroup encoding
  */
 struct generator_t {
        
        /**
-        * @brief Generates a specific payload from given payload object.
+        * Generates a specific payload from given payload object.
         *
         * Remember: Header and substructures are also handled as payloads.
         *
-        * @param this                          generator_t object
-        * @param[in] payload           interface payload_t implementing object
+        * @param payload               interface payload_t implementing object
         */
        void (*generate_payload) (generator_t *this,payload_t *payload);
        
        /**
-        * @brief Writes all generated data of the generator to a chunk.
+        * Writes all generated data of the generator to a chunk.
         *
-        * @param this                          generator_t object
-        * @param[out] 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);
 
        /**
-        * @brief Destroys a generator_t object.
-        *
-        * @param this                          generator_t object
+        * Destroys a generator_t object.
         */
        void (*destroy) (generator_t *this);
 };
 
 /**
- * @brief Constructor to create a generator.
+ * Constructor to create a generator.
  * 
  * @return generator_t object.
- * 
- * @ingroup encoding
  */
 generator_t *generator_create(void);
 
-#endif /*GENERATOR_H_*/
+#endif /*GENERATOR_H_ @} */
index 3dfa64fb9282beaec3c46afe99541d3afa797ec2..0568b42e5aa80ac4be25cf08998d297e31e766e4 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file message.c
- *
- * @brief Implementation of message_t.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
@@ -21,6 +14,8 @@
  * WITHOUT ANY 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>
@@ -82,13 +77,31 @@ struct payload_rule_t {
         bool sufficient;
 };
 
+typedef struct payload_order_t payload_order_t;
+
+/**
+ * payload ordering structure allows us to reorder payloads according to RFC.
+ */
+struct payload_order_t {
+
+       /**
+        * payload type 
+        */
+       payload_type_t type;
+       
+       /** 
+        * notify type, if payload == NOTIFY
+        */
+       notify_type_t notify;
+};
+
+
 typedef struct message_rule_t message_rule_t;
 
 /**
  * A message rule defines the kind of a message,
  * if it has encrypted contents and a list
- * of payload rules.
- * 
+ * of payload ordering rules and payload parsing rules.
  */
 struct message_rule_t {
        /**
@@ -109,124 +122,276 @@ struct message_rule_t {
        /**
         * Number of payload rules which will follow
         */
-       size_t payload_rule_count;
+       int payload_rule_count;
         
        /**
         * Pointer to first payload rule
         */
        payload_rule_t *payload_rules;
+       
+       /**
+        * Number of payload order rules
+        */
+       int payload_order_count;
+       
+       /**
+        * payload ordering rules
+        */
+       payload_order_t *payload_order;
 };
 
 /**
  * Message rule for IKE_SA_INIT from initiator.
  */
 static payload_rule_t ike_sa_init_i_payload_rules[] = {
-       {NOTIFY,0,MAX_NOTIFY_PAYLOADS,FALSE,FALSE},
-       {SECURITY_ASSOCIATION,1,1,FALSE,FALSE},
-       {KEY_EXCHANGE,1,1,FALSE,FALSE},
-       {NONCE,1,1,FALSE,FALSE},
-       {VENDOR_ID,0,10,FALSE,FALSE},
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    FALSE,  FALSE},
+       {SECURITY_ASSOCIATION,                  1,      1,                                              FALSE,  FALSE},
+       {KEY_EXCHANGE,                                  1,      1,                                              FALSE,  FALSE},
+       {NONCE,                                                 1,      1,                                              FALSE,  FALSE},
+       {VENDOR_ID,                                             0,      10,                                             FALSE,  FALSE},
+};
+
+/**
+ * payload order for IKE_SA_INIT initiator
+ */
+static payload_order_t ike_sa_init_i_payload_order[] = {
+/*     payload type                                    notify type */
+       {NOTIFY,                                                COOKIE},
+       {SECURITY_ASSOCIATION,                  0},
+       {KEY_EXCHANGE,                                  0},
+       {NONCE,                                                 0},
+       {NOTIFY,                                                NAT_DETECTION_SOURCE_IP},
+       {NOTIFY,                                                NAT_DETECTION_DESTINATION_IP},
+       {VENDOR_ID,                                             0},
 };
 
 /**
  * Message rule for IKE_SA_INIT from responder.
  */
 static payload_rule_t ike_sa_init_r_payload_rules[] = {
-       {NOTIFY,0,MAX_NOTIFY_PAYLOADS,FALSE,TRUE},
-       {SECURITY_ASSOCIATION,1,1,FALSE,FALSE},
-       {KEY_EXCHANGE,1,1,FALSE,FALSE},
-       {NONCE,1,1,FALSE,FALSE},
-       {VENDOR_ID,0,10,FALSE,FALSE},
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    FALSE,  TRUE},
+       {SECURITY_ASSOCIATION,                  1,      1,                                              FALSE,  FALSE},
+       {KEY_EXCHANGE,                                  1,      1,                                              FALSE,  FALSE},
+       {NONCE,                                                 1,      1,                                              FALSE,  FALSE},
+       {VENDOR_ID,                                             0,      10,                                             FALSE,  FALSE},
+};
+
+/**
+ * payload order for IKE_SA_INIT responder
+ */
+static payload_order_t ike_sa_init_r_payload_order[] = {
+/*     payload type                                    notify type */
+       {SECURITY_ASSOCIATION,                  0},
+       {KEY_EXCHANGE,                                  0},
+       {NONCE,                                                 0},
+       {NOTIFY,                                                NAT_DETECTION_SOURCE_IP},
+       {NOTIFY,                                                NAT_DETECTION_DESTINATION_IP},
+       {NOTIFY,                                                HTTP_CERT_LOOKUP_SUPPORTED},
+       {CERTIFICATE_REQUEST,                   0},
+       {VENDOR_ID,                                             0},
 };
 
 /**
  * Message rule for IKE_AUTH from initiator.
  */
 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},
-       {CERTIFICATE,0,1,TRUE,FALSE},
-       {CERTIFICATE_REQUEST,0,1,TRUE,FALSE},
-       {ID_RESPONDER,0,1,TRUE,FALSE},
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
+       {EXTENSIBLE_AUTHENTICATION,             0,      1,                                              TRUE,   TRUE},
+       {AUTHENTICATION,                                0,      1,                                              TRUE,   TRUE},
+       {ID_INITIATOR,                                  1,      1,                                              TRUE,   FALSE},
+       {CERTIFICATE,                                   0,      4,                                              TRUE,   FALSE},
+       {CERTIFICATE_REQUEST,                   0,      1,                                              TRUE,   FALSE},
+       {ID_RESPONDER,                                  0,      1,                                              TRUE,   FALSE},
 #ifdef P2P
-       {SECURITY_ASSOCIATION,0,1,TRUE,FALSE},
-       {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE},
-       {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE},
+       {SECURITY_ASSOCIATION,                  0,      1,                                              TRUE,   FALSE},
+       {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,                  1,      1,                                              TRUE,   FALSE},
+       {TRAFFIC_SELECTOR_INITIATOR,    1,      1,                                              TRUE,   FALSE},
+       {TRAFFIC_SELECTOR_RESPONDER,    1,      1,                                              TRUE,   FALSE},
 #endif /* P2P */
-       {CONFIGURATION,0,1,TRUE,FALSE},
-       {VENDOR_ID,0,10,TRUE,FALSE},
+       {CONFIGURATION,                                 0,      1,                                              TRUE,   FALSE},
+       {VENDOR_ID,                                             0,      10,                                             TRUE,   FALSE},
+};
+
+/**
+ * payload order for IKE_AUTH initiator
+ */
+static payload_order_t ike_auth_i_payload_order[] = {
+/*     payload type                                    notify type */
+       {ID_INITIATOR,                                  0},
+       {CERTIFICATE,                                   0},
+       {NOTIFY,                                                INITIAL_CONTACT},
+       {NOTIFY,                                                HTTP_CERT_LOOKUP_SUPPORTED},
+       {CERTIFICATE_REQUEST,                   0},
+       {ID_RESPONDER,                                  0},
+       {AUTHENTICATION,                                0},
+       {EXTENSIBLE_AUTHENTICATION,             0},
+       {CONFIGURATION,                                 0},
+       {NOTIFY,                                                IPCOMP_SUPPORTED},
+       {NOTIFY,                                                USE_TRANSPORT_MODE},
+       {NOTIFY,                                                ESP_TFC_PADDING_NOT_SUPPORTED},
+       {NOTIFY,                                                NON_FIRST_FRAGMENTS_ALSO},
+       {SECURITY_ASSOCIATION,                  0},
+       {TRAFFIC_SELECTOR_INITIATOR,    0},
+       {TRAFFIC_SELECTOR_RESPONDER,    0},
+       {NOTIFY,                                                MOBIKE_SUPPORTED},
+       {NOTIFY,                                                ADDITIONAL_IP4_ADDRESS},
+       {NOTIFY,                                                ADDITIONAL_IP6_ADDRESS},
+       {NOTIFY,                                                NO_ADDITIONAL_ADDRESSES},
+       {VENDOR_ID,                                             0},
 };
 
 /**
  * Message rule for IKE_AUTH from responder.
  */
 static payload_rule_t ike_auth_r_payload_rules[] = {
-       {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
-       {EXTENSIBLE_AUTHENTICATION,0,1,TRUE,TRUE},
-       {CERTIFICATE,0,1,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},
-       {CONFIGURATION,0,1,TRUE,FALSE},
-       {VENDOR_ID,0,10,TRUE,FALSE},
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   TRUE},
+       {EXTENSIBLE_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},
+       {CONFIGURATION,                                 0,      1,                                              TRUE,   FALSE},
+       {VENDOR_ID,                                             0,      10,                                             TRUE,   FALSE},
 };
 
+/**
+ * payload order for IKE_AUTH responder
+ */
+static payload_order_t ike_auth_r_payload_order[] = {
+/*     payload type                                    notify type */
+       {ID_RESPONDER,                                  0},
+       {CERTIFICATE,                                   0},
+       {AUTHENTICATION,                                0},
+       {EXTENSIBLE_AUTHENTICATION,             0},
+       {CONFIGURATION,                                 0},
+       {NOTIFY,                                                IPCOMP_SUPPORTED},
+       {NOTIFY,                                                USE_TRANSPORT_MODE},
+       {NOTIFY,                                                ESP_TFC_PADDING_NOT_SUPPORTED},
+       {NOTIFY,                                                NON_FIRST_FRAGMENTS_ALSO},
+       {SECURITY_ASSOCIATION,                  0},
+       {TRAFFIC_SELECTOR_INITIATOR,    0},
+       {TRAFFIC_SELECTOR_RESPONDER,    0},
+       {NOTIFY,                                                AUTH_LIFETIME},
+       {NOTIFY,                                                MOBIKE_SUPPORTED},
+       {NOTIFY,                                                ADDITIONAL_IP4_ADDRESS},
+       {NOTIFY,                                                ADDITIONAL_IP6_ADDRESS},
+       {NOTIFY,                                                NO_ADDITIONAL_ADDRESSES},
+       {VENDOR_ID,                                             0},
+};
 
 /**
  * Message rule for INFORMATIONAL from initiator.
  */
 static payload_rule_t informational_i_payload_rules[] = {
-       {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
-       {CONFIGURATION,0,1,TRUE,FALSE},
-       {DELETE,0,1,TRUE,FALSE},
-       {VENDOR_ID,0,10,TRUE,FALSE},
-       
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
+       {CONFIGURATION,                                 0,      1,                                              TRUE,   FALSE},
+       {DELETE,                                                0,      1,                                              TRUE,   FALSE},
+       {VENDOR_ID,                                             0,      10,                                             TRUE,   FALSE},
+};
+
+/**
+ * payload order for INFORMATIONAL initiator
+ */
+static payload_order_t informational_i_payload_order[] = {
+/*     payload type                                    notify type */
+       {NOTIFY,                                                0},
+       {DELETE,                                                0},
+       {CONFIGURATION,                                 0},
 };
 
 /**
  * Message rule for INFORMATIONAL from responder.
  */
 static payload_rule_t informational_r_payload_rules[] = {
-       {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
-       {CONFIGURATION,0,1,TRUE,FALSE},
-       {DELETE,0,1,TRUE,FALSE},
-       {VENDOR_ID,0,10,TRUE,FALSE},
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
+       {CONFIGURATION,                                 0,      1,                                              TRUE,   FALSE},
+       {DELETE,                                                0,      1,                                              TRUE,   FALSE},
+       {VENDOR_ID,                                             0,      10,                                             TRUE,   FALSE},
+};
+
+/**
+ * payload order for INFORMATIONAL responder
+ */
+static payload_order_t informational_r_payload_order[] = {
+/*     payload type                                    notify type */
+       {NOTIFY,                                                0},
+       {DELETE,                                                0},
+       {CONFIGURATION,                                 0},
 };
 
 /**
  * Message rule for CREATE_CHILD_SA from initiator.
  */
 static payload_rule_t create_child_sa_i_payload_rules[] = {
-       {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,FALSE},
-       {SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
-       {NONCE,1,1,TRUE,FALSE},
-       {KEY_EXCHANGE,0,1,TRUE,FALSE},
-       {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE},
-       {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE},
-       {CONFIGURATION,0,1,TRUE,FALSE},
-       {VENDOR_ID,0,10,TRUE,FALSE},
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
+       {SECURITY_ASSOCIATION,                  1,      1,                                              TRUE,   FALSE},
+       {NONCE,                                                 1,      1,                                              TRUE,   FALSE},
+       {KEY_EXCHANGE,                                  0,      1,                                              TRUE,   FALSE},
+       {TRAFFIC_SELECTOR_INITIATOR,    0,      1,                                              TRUE,   FALSE},
+       {TRAFFIC_SELECTOR_RESPONDER,    0,      1,                                              TRUE,   FALSE},
+       {CONFIGURATION,                                 0,      1,                                              TRUE,   FALSE},
+       {VENDOR_ID,                                             0,      10,                                             TRUE,   FALSE},
+};
+
+/**
+ * payload order for CREATE_CHILD_SA from initiator.
+ */
+static payload_order_t create_child_sa_i_payload_order[] = {
+/*     payload type                                    notify type */
+       {NOTIFY,                                                REKEY_SA},
+       {NOTIFY,                                                IPCOMP_SUPPORTED},
+       {NOTIFY,                                                USE_TRANSPORT_MODE},
+       {NOTIFY,                                                ESP_TFC_PADDING_NOT_SUPPORTED},
+       {NOTIFY,                                                NON_FIRST_FRAGMENTS_ALSO},
+       {SECURITY_ASSOCIATION,                  0},
+       {NONCE,                                                 0},
+       {KEY_EXCHANGE,                                  0},
+       {TRAFFIC_SELECTOR_INITIATOR,    0},
+       {TRAFFIC_SELECTOR_RESPONDER,    0},
 };
 
 /**
  * Message rule for CREATE_CHILD_SA from responder.
  */
 static payload_rule_t create_child_sa_r_payload_rules[] = {
-       {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
-       {SECURITY_ASSOCIATION,1,1,TRUE,FALSE},
-       {NONCE,1,1,TRUE,FALSE},
-       {KEY_EXCHANGE,0,1,TRUE,FALSE},
-       {TRAFFIC_SELECTOR_INITIATOR,0,1,TRUE,FALSE},
-       {TRAFFIC_SELECTOR_RESPONDER,0,1,TRUE,FALSE},
-       {CONFIGURATION,0,1,TRUE,FALSE},
-       {VENDOR_ID,0,10,TRUE,FALSE},
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   TRUE},
+       {SECURITY_ASSOCIATION,                  1,      1,                                              TRUE,   FALSE},
+       {NONCE,                                                 1,      1,                                              TRUE,   FALSE},
+       {KEY_EXCHANGE,                                  0,      1,                                              TRUE,   FALSE},
+       {TRAFFIC_SELECTOR_INITIATOR,    0,      1,                                              TRUE,   FALSE},
+       {TRAFFIC_SELECTOR_RESPONDER,    0,      1,                                              TRUE,   FALSE},
+       {CONFIGURATION,                                 0,      1,                                              TRUE,   FALSE},
+       {VENDOR_ID,                                             0,      10,                                             TRUE,   FALSE},
+};
+
+/**
+ * payload order for CREATE_CHILD_SA from responder.
+ */
+static payload_order_t create_child_sa_r_payload_order[] = {
+/*     payload type                                    notify type */
+       {NOTIFY,                                                IPCOMP_SUPPORTED},
+       {NOTIFY,                                                USE_TRANSPORT_MODE},
+       {NOTIFY,                                                ESP_TFC_PADDING_NOT_SUPPORTED},
+       {NOTIFY,                                                NON_FIRST_FRAGMENTS_ALSO},
+       {SECURITY_ASSOCIATION,                  0},
+       {NONCE,                                                 0},
+       {KEY_EXCHANGE,                                  0},
+       {TRAFFIC_SELECTOR_INITIATOR,    0},
+       {TRAFFIC_SELECTOR_RESPONDER,    0},
+       {NOTIFY,                                                ADDITIONAL_TS_POSSIBLE},
 };
 
 #ifdef P2P
@@ -234,17 +399,38 @@ static payload_rule_t create_child_sa_r_payload_rules[] = {
  * Message rule for P2P_CONNECT from initiator.
  */
 static payload_rule_t p2p_connect_i_payload_rules[] = {
-       {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
-       {ID_PEER,1,1,TRUE,FALSE},
-       {VENDOR_ID,0,10,TRUE,FALSE}
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   TRUE},
+       {ID_PEER,                                               1,      1,                                              TRUE,   FALSE},
+       {VENDOR_ID,                                             0,      10,                                             TRUE,   FALSE}
+};
+
+/**
+ * payload order for P2P_CONNECT from initiator.
+ */
+static payload_order_t p2p_connect_i_payload_order[] = {
+/*     payload type                                    notify type */
+       {NOTIFY,                                                0},
+       {ID_PEER,                                               0},
+       {VENDOR_ID,                                             0},
 };
 
 /**
  * Message rule for P2P_CONNECT from responder.
  */
 static payload_rule_t p2p_connect_r_payload_rules[] = {
-       {NOTIFY,0,MAX_NOTIFY_PAYLOADS,TRUE,TRUE},
-       {VENDOR_ID,0,10,TRUE,FALSE}
+/*     payload type                                    min     max                                             encr    suff */
+       {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   TRUE},
+       {VENDOR_ID,                                             0,      10,                                             TRUE,   FALSE}
+};
+
+/**
+ * payload order for P2P_CONNECT from responder.
+ */
+static payload_order_t p2p_connect_r_payload_order[] = {
+/*     payload type                                    notify type */
+       {NOTIFY,                                                0},
+       {VENDOR_ID,                                             0},
 };
 #endif /* P2P */
 
@@ -252,17 +438,67 @@ static payload_rule_t p2p_connect_r_payload_rules[] = {
  * Message rules, defines allowed payloads.
  */
 static message_rule_t message_rules[] = {
-       {IKE_SA_INIT,TRUE,FALSE,(sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_i_payload_rules},
-       {IKE_SA_INIT,FALSE,FALSE,(sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)),ike_sa_init_r_payload_rules},
-       {IKE_AUTH,TRUE,TRUE,(sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),ike_auth_i_payload_rules},
-       {IKE_AUTH,FALSE,TRUE,(sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),ike_auth_r_payload_rules},
-       {INFORMATIONAL,TRUE,TRUE,(sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)),informational_i_payload_rules},
-       {INFORMATIONAL,FALSE,TRUE,(sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),informational_r_payload_rules},
-       {CREATE_CHILD_SA,TRUE,TRUE,(sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)),create_child_sa_i_payload_rules},
-       {CREATE_CHILD_SA,FALSE,TRUE,(sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)),create_child_sa_r_payload_rules},
+       {IKE_SA_INIT,           TRUE,   FALSE,
+               (sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)),
+               ike_sa_init_i_payload_rules,
+               (sizeof(ike_sa_init_i_payload_order)/sizeof(payload_order_t)),
+               ike_sa_init_i_payload_order,
+       },
+       {IKE_SA_INIT,           FALSE,  FALSE,
+               (sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)),
+               ike_sa_init_r_payload_rules,
+               (sizeof(ike_sa_init_r_payload_order)/sizeof(payload_order_t)),
+               ike_sa_init_r_payload_order,
+       },
+       {IKE_AUTH,                      TRUE,   TRUE,
+               (sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),
+               ike_auth_i_payload_rules,
+               (sizeof(ike_auth_i_payload_order)/sizeof(payload_order_t)),
+               ike_auth_i_payload_order,
+       },
+       {IKE_AUTH,                      FALSE,  TRUE,
+               (sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),
+               ike_auth_r_payload_rules,
+               (sizeof(ike_auth_r_payload_order)/sizeof(payload_order_t)),
+               ike_auth_r_payload_order,
+       },
+       {INFORMATIONAL,         TRUE,   TRUE,
+               (sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)),
+               informational_i_payload_rules,
+               (sizeof(informational_i_payload_order)/sizeof(payload_order_t)),
+               informational_i_payload_order,
+       },
+       {INFORMATIONAL,         FALSE,  TRUE,
+               (sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),
+               informational_r_payload_rules,
+               (sizeof(informational_r_payload_order)/sizeof(payload_order_t)),
+               informational_r_payload_order,
+       },
+       {CREATE_CHILD_SA,       TRUE,   TRUE,
+               (sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)),
+               create_child_sa_i_payload_rules,
+               (sizeof(create_child_sa_i_payload_order)/sizeof(payload_order_t)),
+               create_child_sa_i_payload_order,
+       },
+       {CREATE_CHILD_SA,       FALSE,  TRUE,
+               (sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)),
+               create_child_sa_r_payload_rules,
+               (sizeof(create_child_sa_r_payload_order)/sizeof(payload_order_t)),
+               create_child_sa_r_payload_order,
+       },
 #ifdef P2P
-       {P2P_CONNECT,TRUE,TRUE,(sizeof(p2p_connect_i_payload_rules)/sizeof(payload_rule_t)),p2p_connect_i_payload_rules},
-       {P2P_CONNECT,FALSE,TRUE,(sizeof(p2p_connect_r_payload_rules)/sizeof(payload_rule_t)),p2p_connect_r_payload_rules},
+       {P2P_CONNECT,           TRUE,   TRUE,
+               (sizeof(p2p_connect_i_payload_rules)/sizeof(payload_rule_t)),
+               p2p_connect_i_payload_rules,
+               (sizeof(p2p_connect_i_payload_order)/sizeof(payload_order_t)),
+               p2p_connect_i_payload_order,
+       },
+       {P2P_CONNECT,           FALSE,  TRUE,
+               (sizeof(p2p_connect_r_payload_rules)/sizeof(payload_rule_t)),
+               p2p_connect_r_payload_rules,
+               (sizeof(p2p_connect_r_payload_order)/sizeof(payload_order_t)),
+               p2p_connect_r_payload_order,
+       },
 #endif /* P2P */       
 };
 
@@ -517,38 +753,19 @@ static bool is_encoded(private_message_t *this)
  */
 static void add_payload(private_message_t *this, payload_t *payload)
 {
-       payload_t *last_payload, *first_payload;
-       
-       if ((this->is_request && payload->get_type(payload) == ID_INITIATOR) ||
-               (!this->is_request && payload->get_type(payload) == ID_RESPONDER))
+       payload_t *last_payload;
+
+       if (this->payloads->get_count(this->payloads) > 0)
        {
-               /* HOTD: insert ID payload in the beginning to respect RFC */
-               if (this->payloads->get_first(this->payloads,
-                                                                         (void **)&first_payload) == SUCCESS)
-               {
-                       payload->set_next_type(payload, first_payload->get_type(first_payload));
-               }
-               else
-               {
-                       payload->set_next_type(payload, NO_PAYLOAD);
-               }
-               this->first_payload = payload->get_type(payload);
-               this->payloads->insert_first(this->payloads, payload);
+               this->payloads->get_last(this->payloads, (void **)&last_payload);
+               last_payload->set_next_type(last_payload, payload->get_type(payload));
        }
        else
        {
-               if (this->payloads->get_count(this->payloads) > 0)
-               {
-                       this->payloads->get_last(this->payloads,(void **) &last_payload);
-                       last_payload->set_next_type(last_payload, payload->get_type(payload));
-               }
-               else
-               {
-                       this->first_payload = payload->get_type(payload);
-               }
-               payload->set_next_type(payload, NO_PAYLOAD);
-               this->payloads->insert_last(this->payloads, payload);
+               this->first_payload = payload->get_type(payload);
        }
+       payload->set_next_type(payload, NO_PAYLOAD);
+       this->payloads->insert_last(this->payloads, payload);
 
        DBG2(DBG_ENC ,"added payload of type %N to message",
                 payload_type_names, payload->get_type(payload));
@@ -693,10 +910,66 @@ static char* get_string(private_message_t *this, char *buf, int len)
        return buf;
 }
 
+/**
+ * reorder payloads depending on reordering rules
+ */
+static void order_payloads(private_message_t *this)
+{
+       linked_list_t *list;
+       payload_t *payload;
+       int i;
+       
+       /* move to temp list */
+       list = linked_list_create();
+       while (this->payloads->remove_last(this->payloads,
+                                                                          (void**)&payload) == SUCCESS)
+       {
+               list->insert_first(list, payload);
+       }
+       /* for each rule, ... */
+       for (i = 0; i < this->message_rule->payload_order_count; i++)
+       {
+               enumerator_t *enumerator;
+               notify_payload_t *notify;
+               payload_order_t order = this->message_rule->payload_order[i];
+               
+               /* ... find all payload ... */
+               enumerator = list->create_enumerator(list);
+               while (enumerator->enumerate(enumerator, &payload))
+               {
+                       /* ... with that type ... */
+                       if (payload->get_type(payload) == order.type)
+                       {
+                               notify = (notify_payload_t*)payload;
+                       
+                               /**... and check notify for type. */
+                               if (order.type != NOTIFY || order.notify == 0 ||
+                                       order.notify == notify->get_notify_type(notify))
+                               {
+                                       list->remove_at(list, enumerator);
+                                       add_payload(this, payload);
+                               }
+                       } 
+               }
+               enumerator->destroy(enumerator);
+       }
+       /* append all payloads without a rule to the end */
+       while (list->remove_last(list, (void**)&payload) == SUCCESS)
+       {
+               DBG1(DBG_ENC, "payload %N has no ordering rule in %N %s",
+                        payload_type_names, payload->get_type(payload),
+                        exchange_type_names, this->message_rule->exchange_type,
+                        this->message_rule->is_request ? "request" : "response");
+               add_payload(this, payload);
+       }
+       list->destroy(list);
+}
+
 /**
  * Implementation of private_message_t.encrypt_payloads.
  */
-static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, signer_t* signer)
+static status_t encrypt_payloads(private_message_t *this,
+                                                                crypter_t *crypter, signer_t* signer)
 {
        encryption_payload_t *encryption_payload = NULL;
        status_t status;
@@ -778,7 +1051,8 @@ static status_t encrypt_payloads (private_message_t *this,crypter_t *crypter, si
 /**
  * Implementation of message_t.generate.
  */
-static status_t generate(private_message_t *this, crypter_t *crypter, signer_t* signer, packet_t **packet)
+static status_t generate(private_message_t *this, crypter_t *crypter,
+                                                signer_t* signer, packet_t **packet)
 {
        generator_t *generator;
        ike_header_t *ike_header;
@@ -795,8 +1069,6 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
                return SUCCESS;
        }
        
-       DBG1(DBG_ENC, "generating %s", get_string(this, str, sizeof(str)));
-       
        if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED)
        {
                DBG1(DBG_ENC, "exchange type is not defined");
@@ -819,6 +1091,10 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
                return NOT_SUPPORTED;
        }
        
+       order_payloads(this);
+       
+       DBG1(DBG_ENC, "generating %s", get_string(this, str, sizeof(str)));
+       
        /* going to encrypt all content which have to be encrypted */
        status = encrypt_payloads(this, crypter, signer);
        if (status != SUCCESS)
@@ -842,7 +1118,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter, signer_t*
        payload = (payload_t*)ike_header;
 
        
-       /* generate every payload expect last one, this is doen later*/
+       /* 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))
        {
@@ -1346,3 +1622,4 @@ message_t *message_create()
 {
        return message_create_from_packet(NULL);
 }
+
index 35b659f33a36354deed66dc3faf24fabd896db26..a7637b90c4479d63cf64ca2c8b0c54ac380f6c99 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file message.h
- *
- * @brief Interface of message_t.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * WITHOUT ANY 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 message message
+ * @{ @ingroup encoding
  */
 
 #ifndef MESSAGE_H_
@@ -38,148 +38,126 @@ typedef struct message_t message_t;
 #include <crypto/signers/signer.h>
 
 /**
- * @brief This class is used to represent an IKEv2-Message.
+ * This class is used to represent an IKEv2-Message.
  *
  * The message handles parsing and generation of payloads
  * via parser_t/generator_t. Encryption is done transparently
  * via the encryption_payload_t. A set of rules for messages
  * and payloads does check parsed messages.
- * 
- * @b Constructors:
- * - message_create()
- * - message_create_from_packet()
- * - message_create_notify_reply()
- *
- * @ingroup encoding
  */
 struct message_t {
 
        /**
-        * @brief Sets the IKE major version of the message.
+        * Sets the IKE major version of the message.
         *
-        * @param this                  message_t object
         * @param major_version major version to set
         */
        void (*set_major_version) (message_t *this,u_int8_t major_version);
 
        /**
-        * @brief Gets the IKE major version of the message.
+        * Gets the IKE major version of the message.
         *
-        * @param this                  message_t object
         * @return                              major version of the message
         */
        u_int8_t (*get_major_version) (message_t *this);
        
        /**
-        * @brief Sets the IKE minor version of the message.
+        * Sets the IKE minor version of the message.
         *
-        * @param this                  message_t object
         * @param minor_version minor version to set
         */
        void (*set_minor_version) (message_t *this,u_int8_t minor_version);
 
        /**
-        * @brief Gets the IKE minor version of the message.
+        * Gets the IKE minor version of the message.
         *
-        * @param this                  message_t object
         * @return                              minor version of the message
         */
        u_int8_t (*get_minor_version) (message_t *this);
 
        /**
-        * @brief Sets the Message ID of the message.
+        * Sets the Message ID of the message.
         *
-        * @param this                  message_t object
-        * @param message_id            message_id to set
+        * @param message_id    message_id to set
         */
        void (*set_message_id) (message_t *this,u_int32_t message_id);
 
        /**
-        * @brief Gets the Message ID of the message.
+        * Gets the Message ID of the message.
         *
-        * @param this                  message_t object
         * @return                              message_id type of the message
         */
        u_int32_t (*get_message_id) (message_t *this);
        
        /**
-        * @brief Gets the initiator SPI of the message.
+        * Gets the initiator SPI of the message.
         *
-        * @param this                  message_t object
         * @return                              initiator spi of the message
         */
        u_int64_t (*get_initiator_spi) (message_t *this);
 
        /**
-        * @brief Gets the responder SPI of the message.
+        * Gets the responder SPI of the message.
         *
-        * @param this                  message_t object
         * @return                              responder spi of the message
         */
        u_int64_t (*get_responder_spi) (message_t *this);
 
        /**
-        * @brief Sets the IKE_SA ID of the message.
+        * Sets the IKE_SA ID of the message.
         * 
         * ike_sa_id gets cloned.
         *
-        * @param this                  message_t object
         * @param ike_sa_id             ike_sa_id to set
         */
        void (*set_ike_sa_id) (message_t *this, ike_sa_id_t * ike_sa_id);
 
        /**
-        * @brief Gets the IKE_SA ID of the message.
+        * Gets the IKE_SA ID of the message.
         *
         * The ike_sa_id points to the message internal id, do not modify.
         *
-        * @param this                  message_t object
         * @return                              ike_sa_id of message
         */
        ike_sa_id_t *(*get_ike_sa_id) (message_t *this);
 
        /**
-        * @brief Sets the exchange type of the message.
+        * Sets the exchange type of the message.
         *
-        * @param this                  message_t object
         * @param exchange_type exchange_type to set
         */
        void (*set_exchange_type) (message_t *this,exchange_type_t exchange_type);
 
        /**
-        * @brief Gets the exchange type of the message.
+        * Gets the exchange type of the message.
         *
-        * @param this                  message_t object
         * @return                              exchange type of the message
         */
        exchange_type_t (*get_exchange_type) (message_t *this);
        
        /**
-        * @brief Gets the payload type of the first payload.
+        * Gets the payload type of the first payload.
         * 
-        * @param this                  message_t object
         * @return                              payload type of the first payload
         */
        payload_type_t (*get_first_payload_type) (message_t *this);
 
        /**
-        * @brief Sets the request flag.
+        * Sets the request flag.
         *
-        * @param this                                  message_t object
-        * @param original_initiator            TRUE if message is a request, FALSE if it is a reply
+        * @param request               TRUE if message is a request, FALSE if it is a reply
         */
-       void (*set_request) (message_t *this,bool request);
+       void (*set_request) (message_t *this, bool request);
 
        /**
-        * @brief Gets request flag.
+        * Gets request flag.
         *
-        * @param this                  message_t object
         * @return                              TRUE if message is a request, FALSE if it is a reply
         */
        bool (*get_request) (message_t *this);
 
        /**
-        * @brief Append a payload to the message.
+        * Append a payload to the message.
         * 
         * If the payload must be encrypted is not specified here. Encryption
         * of payloads is evaluated via internal rules for the messages and
@@ -187,19 +165,17 @@ struct message_t {
         * all payloads to encrypt are added to the encryption payload, which is 
         * always the last one.
         *
-        * @param this                  message_t object
         * @param payload               payload to append
         */     
        void (*add_payload) (message_t *this, payload_t *payload);
 
        /**
-        * @brief Build a notify payload and add it to the message.
+        * Build a notify payload and add it to the message.
         * 
         * This is a helper method to create notify messages or add
         * notify payload to messages. The flush parameter specifies if existing
         * payloads should get removed before appending the notify.
         *
-        * @param this                  message_t object
         * @param flush                 TRUE to remove existing payloads
         * @param type                  type of the notify
         * @param data                  a chunk of data to add to the notify, gets cloned
@@ -208,13 +184,12 @@ struct message_t {
                                                chunk_t data);
 
        /**
-        * @brief Parses header of message.
+        * Parses header of message.
         * 
         * Begins parisng of a message created via message_create_from_packet().
         * The parsing context is stored, so a subsequent call to parse_body()
         * will continue the parsing process.
         *
-        * @param this          message_t object
         * @return
         *                                      - SUCCESS if header could be parsed
         *                                      - PARSE_ERROR if corrupted/invalid data found
@@ -223,7 +198,7 @@ struct message_t {
        status_t (*parse_header) (message_t *this);
        
        /**
-        * @brief Parses body of message.
+        * Parses body of message.
         * 
         * The body gets not only parsed, but rather it gets verified. 
         * All payloads are verified if they are allowed to exist in the message 
@@ -234,7 +209,6 @@ struct message_t {
         * Crypter/signer can be omitted (by passing NULL) when no encryption 
         * payload is expected.
         *
-        * @param this          message_t object
         * @param crypter       crypter to decrypt encryption payloads
         * @param signer        signer to verifiy a message with an encryption payload
         * @return
@@ -249,7 +223,7 @@ struct message_t {
        status_t (*parse_body) (message_t *this, crypter_t *crypter, signer_t *signer);
 
        /**
-        * @brief Generates the UDP packet of specific message.
+        * Generates the UDP packet of specific message.
         * 
         * Payloads which must be encrypted are generated first and added to
         * an encryption payload. This encryption payload will get encrypted via 
@@ -260,7 +234,6 @@ struct message_t {
         * payload is expected.
         * Generation is only done once, multiple calls will just return a packet copy.
         *
-        * @param this          message_t object
         * @param crypter       crypter to use when a payload must be encrypted
         * @param signer        signer to build a mac
         * @param packet        copy of generated packet
@@ -273,103 +246,91 @@ struct message_t {
        status_t (*generate) (message_t *this, crypter_t *crypter, signer_t *signer, packet_t **packet);
 
        /**
-        * @brief Gets the source host informations. 
+        * Gets the source host informations. 
         * 
         * @warning Returned host_t object is not getting cloned, 
         * do not destroy nor modify.
         *
-        * @param this          message_t object
         * @return                      host_t object representing source host
         */     
        host_t * (*get_source) (message_t *this);
        
        /**
-        * @brief Sets the source host informations. 
+        * Sets the source host informations. 
         * 
         * @warning host_t object is not getting cloned and gets destroyed by
         *                      message_t.destroy or next call of message_t.set_source.
         *
-        * @param this          message_t object
         * @param host          host_t object representing source host
         */     
        void (*set_source) (message_t *this, host_t *host);
 
        /**
-        * @brief Gets the destination host informations. 
+        * Gets the destination host informations. 
         * 
         * @warning Returned host_t object is not getting cloned, 
         * do not destroy nor modify.
         *
-        * @param this          message_t object
         * @return                      host_t object representing destination host
         */     
        host_t * (*get_destination) (message_t *this);
 
        /**
-        * @brief Sets the destination host informations. 
+        * Sets the destination host informations. 
         * 
         * @warning host_t object is not getting cloned and gets destroyed by
         *                      message_t.destroy or next call of message_t.set_destination.
         *
-        * @param this          message_t object
         * @param host          host_t object representing destination host
         */     
        void (*set_destination) (message_t *this, host_t *host);
        
        /**
-        * @brief Returns an iterator on all stored payloads.
+        * Returns an iterator on all stored payloads.
         * 
         * @warning Don't insert payloads over this iterator. 
         *                      Use add_payload() instead.
         *
-        * @param this          message_t object
         * @return                      iterator_t object which has to get destroyd by the caller
         */     
        iterator_t * (*get_payload_iterator) (message_t *this);
        
        /**
-        * @brief Find a payload of a specific type.
+        * Find a payload of a specific type.
         * 
         * Returns the first occurance. 
         *
-        * @param this          message_t object
         * @param type          type of the payload to find
         * @return                      payload, or NULL if no such payload found
         */     
        payload_t* (*get_payload) (message_t *this, payload_type_t type);
        
        /**
-        * @brief Returns a clone of the internal stored packet_t object.
+        * Returns a clone of the internal stored packet_t object.
         *
-        * @param this          message_t object
         * @return                      packet_t object as clone of internal one
         */     
        packet_t * (*get_packet) (message_t *this);
        
        /**
-        * @brief Returns a clone of the internal stored packet_t data.
+        * Returns a clone of the internal stored packet_t data.
         *
-        * @param this          message_t object
         * @return                      clone of the internal stored packet_t data.
         */     
        chunk_t (*get_packet_data) (message_t *this);
        
        /**
-        * @brief Destroys a message and all including objects.
-        *
-        * @param this          message_t object
+        * Destroys a message and all including objects.
         */
        void (*destroy) (message_t *this);
 };
 
 /**
- * @brief Creates an message_t object from a incoming UDP Packet.
+ * Creates an message_t object from a incoming UDP Packet.
  * 
  * @warning the given packet_t object is not copied and gets 
  *                     destroyed in message_t's destroy call.
  * 
- * @warning Packet is not parsed in here!
- * 
  * - exchange_type is set to NOT_SET
  * - original_initiator is set to TRUE
  * - is_request is set to TRUE
@@ -377,23 +338,19 @@ struct message_t {
  * 
  * @param packet               packet_t object which is assigned to message    
  * @return                             message_t object
- * 
- * @ingroup encoding
  */
 message_t * message_create_from_packet(packet_t *packet);
 
 
 /**
- * @brief Creates an empty message_t object.
+ * Creates an empty message_t object.
  *
  * - exchange_type is set to NOT_SET
  * - original_initiator is set to TRUE
  * - is_request is set to TRUE
  * 
  * @return message_t object
- *
- * @ingroup encoding
  */
 message_t * message_create(void);
 
-#endif /*MESSAGE_H_*/
+#endif /*MESSAGE_H_ @} */
index d7caf70991b7de498b29bdeb6dc64dfa8e3efa40..161ceff94831d8bd2ede4853b7d538cd9700cbfa 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file parser.c
- *
- * @brief Implementation of parser_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
@@ -67,7 +62,7 @@ struct private_parser_t {
        parser_t public;
        
        /**
-        * @brief Parse a 4-Bit unsigned integer from the current parsing position.
+        * Parse a 4-Bit unsigned integer from the current parsing position.
         * 
         * @param this                          parser_t object
         * @param rule_number           number of current rule
@@ -79,7 +74,7 @@ struct private_parser_t {
        status_t (*parse_uint4)  (private_parser_t *this, int rule_number, u_int8_t *output_pos);
        
        /**
-        * @brief Parse a 8-Bit unsigned integer from the current parsing position.
+        * Parse a 8-Bit unsigned integer from the current parsing position.
         * 
         * @param this                          parser_t object
         * @param rule_number           number of current rule
@@ -91,7 +86,7 @@ struct private_parser_t {
        status_t (*parse_uint8)  (private_parser_t *this, int rule_number, u_int8_t *output_pos);
        
        /**
-        * @brief Parse a 15-Bit unsigned integer from the current parsing position.
+        * Parse a 15-Bit unsigned integer from the current parsing position.
         * 
         * This is a special case used for ATTRIBUTE_TYPE.
         * Big-/Little-endian conversion is done here.
@@ -106,7 +101,7 @@ struct private_parser_t {
        status_t (*parse_uint15) (private_parser_t *this, int rule_number, u_int16_t *output_pos);
        
        /**
-        * @brief Parse a 16-Bit unsigned integer from the current parsing position.
+        * Parse a 16-Bit unsigned integer from the current parsing position.
         * 
         * Big-/Little-endian conversion is done here.
         * 
@@ -120,7 +115,7 @@ struct private_parser_t {
        status_t (*parse_uint16) (private_parser_t *this, int rule_number, u_int16_t *output_pos);
        
        /**
-        * @brief Parse a 32-Bit unsigned integer from the current parsing position.
+        * Parse a 32-Bit unsigned integer from the current parsing position.
         * 
         * Big-/Little-endian conversion is done here.
         * 
@@ -134,7 +129,7 @@ struct private_parser_t {
        status_t (*parse_uint32) (private_parser_t *this, int rule_number, u_int32_t *output_pos);
        
        /**
-        * @brief Parse a 64-Bit unsigned integer from the current parsing position.
+        * Parse a 64-Bit unsigned integer from the current parsing position.
         * 
         * @todo add support for big-endian machines.
         * 
@@ -148,7 +143,7 @@ struct private_parser_t {
        status_t (*parse_uint64) (private_parser_t *this, int rule_number, u_int64_t *output_pos);
        
        /**
-        * @brief Parse a given amount of bytes and writes them to a specific location
+        * Parse a given amount of bytes and writes them to a specific location
         * 
         * @param this                          parser_t object
         * @param rule_number           number of current rule
@@ -161,7 +156,7 @@ struct private_parser_t {
        status_t (*parse_bytes) (private_parser_t *this, int rule_number, u_int8_t *output_pos,size_t bytes);
        
        /**
-        * @brief Parse a single Bit from the current parsing position
+        * Parse a single Bit from the current parsing position
         * 
         * @param this                          parser_t object
         * @param rule_number           number of current rule
@@ -173,7 +168,7 @@ struct private_parser_t {
        status_t (*parse_bit)    (private_parser_t *this, int rule_number, bool *output_pos);
        
        /**
-        * @brief Parse substructures in a list
+        * Parse substructures in a list
         * 
         * This function calls the parser recursively to parse contained substructures
         * in a linked_list_t. The list must already be created. Payload defines
@@ -192,7 +187,7 @@ struct private_parser_t {
        status_t (*parse_list)   (private_parser_t *this, int rule_number, linked_list_t **output_pos, payload_type_t payload_ype, size_t length);
        
        /**
-        * @brief Parse data from current parsing position in a chunk.
+        * Parse data from current parsing position in a chunk.
         * 
         * This function clones length number of bytes to output_pos, without 
         * modifiyng them. Space will be allocated and must be freed by caller.
index e9978524cf491782b8c9c3d8160dda27ddd6f7b1..d3bcbc20fb9653a444f98323f2000f59a39ad2d7 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file parser.h
- *
- * @brief Interface of parser_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 parser parser
+ * @{ @ingroup encoding
  */
 
 #ifndef PARSER_H_
@@ -31,65 +31,51 @@ typedef struct parser_t parser_t;
 #include <encoding/payloads/payload.h>
 
 /**
- * @brief A parser_t class to parse IKEv2 payloads.
+ * A parser_t class to parse IKEv2 payloads.
  *
  * A parser is used for parsing one chunk of data. Multiple
  * payloads can be parsed out of the chunk using parse_payload.
  * The parser remains the state until destroyed.
- *
- * @b Constructors:
- * - parser_create()
- *
- * @ingroup encoding
  */
 struct parser_t {
        
        /**
-        * @brief Parses the next payload.
+        * Parses the next payload.
         * 
         * @warning Caller is responsible for freeing allocated payload.
         * 
         * Rules for parsing are described in the payload definition.
         *
-        * @param this                          parser_t bject
-        * @param payload_type          payload type to parse
-        * @param[out] payload          pointer where parsed payload was allocated
+        * @param payload_type  payload type to parse
+        * @param payload               pointer where parsed payload was allocated
         * @return                      
-        *                                                      - SUCCESSFUL if succeeded,
-        *                                                      - PARSE_ERROR if corrupted/invalid data found
+        *                                              - SUCCESSFUL if succeeded,
+        *                                              - PARSE_ERROR if corrupted/invalid data found
         */
        status_t (*parse_payload) (parser_t *this, payload_type_t payload_type, payload_t **payload);
        
        /**
         * Gets the remaining byte count which is not currently parsed.
-        * 
-        * @param parser                parser_t object
         */
        int (*get_remaining_byte_count) (parser_t *this);
        
        /**
-        * @brief Resets the current parser context.
-        *
-        * @param parser                parser_t object
+        * Resets the current parser context.
         */
        void (*reset_context) (parser_t *this);
        
        /**
-        * @brief Destroys a parser_t object.
-        *
-        * @param parser                parser_t object
+        * Destroys a parser_t object.
         */
        void (*destroy) (parser_t *this);
 };
 
 /**
- * @brief Constructor to create a parser_t object.
- * 
- * @param data                         chunk of data to parse with this parser_t object
- * @return                                     parser_t object
+ * Constructor to create a parser_t object.
  * 
- * @ingroup encoding
+ * @param data         chunk of data to parse with this parser_t object
+ * @return                     parser_t object
  */
 parser_t *parser_create(chunk_t data);
 
-#endif /*PARSER_H_*/
+#endif /*PARSER_H_ @} */
index 256d6c8a4df90daa4facb3c4c11081fa1b0c5820..5df9e90235490d84b3f46dd1c020a0ad58572623 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file auth_payload.h
- * 
- * @brief Implementation of auth_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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_payload.h"
index 2db82ec0b68bc8a37afdc88298de5efed60f34a6..6e0596c4bd634cf65a771005198fdec09907d7d1 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file auth_payload.h
- * 
- * @brief Interface of auth_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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_payload auth_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef AUTH_PAYLOAD_H_
@@ -32,20 +32,13 @@ typedef struct auth_payload_t auth_payload_t;
 
 /**
  * Length of a auth payload without the auth data in bytes.
- * 
- * @ingroup payloads
  */
 #define AUTH_PAYLOAD_HEADER_LENGTH 8
 
 /**
- * @brief Class representing an IKEv2 AUTH payload.
+ * Class representing an IKEv2 AUTH payload.
  *
  * The AUTH payload format is described in RFC section 3.8.
- *
- * @b Constructors:
- * - auth_payload_create()
- *
- * @ingroup payloads
  */
 struct auth_payload_t {
        
@@ -55,67 +48,57 @@ struct auth_payload_t {
        payload_t payload_interface;
 
        /**
-        * @brief Set the AUTH method.
+        * Set the AUTH method.
         *
-        * @param this                  calling auth_payload_t object
         * @param method                auth_method_t to use
         */
        void (*set_auth_method) (auth_payload_t *this, auth_method_t method);
        
        /**
-        * @brief Get the AUTH method.
+        * Get the AUTH method.
         *
-        * @param this                  calling auth_payload_t object
         * @return                              auth_method_t used
         */
        auth_method_t (*get_auth_method) (auth_payload_t *this);
        
        /**
-        * @brief Set the AUTH data.
+        * Set the AUTH data.
         * 
-        * Data are getting cloned.
+        * Data gets cloned.
         *
-        * @param this                  calling auth_payload_t object
         * @param data                  AUTH data as chunk_t
         */
        void (*set_data) (auth_payload_t *this, chunk_t data);
        
        /**
-        * @brief Get the AUTH data.
+        * Get the AUTH data.
         * 
         * Returned data are a copy of the internal one.
         *
-        * @param this                  calling auth_payload_t object
         * @return                              AUTH data as chunk_t
         */
        chunk_t (*get_data_clone) (auth_payload_t *this);
        
        /**
-        * @brief Get the AUTH data.
+        * Get the AUTH data.
         * 
         * Returned data are NOT copied
         *
-        * @param this                  calling auth_payload_t object
         * @return                              AUTH data as chunk_t
         */
        chunk_t (*get_data) (auth_payload_t *this);
        
        /**
-        * @brief Destroys an auth_payload_t object.
-        *
-        * @param this                  auth_payload_t object to destroy
+        * Destroys an auth_payload_t object.
         */
        void (*destroy) (auth_payload_t *this);
 };
 
 /**
- * @brief Creates an empty auth_payload_t object.
+ * Creates an empty auth_payload_t object.
  * 
  * @return auth_payload_t object
- * 
- * @ingroup payloads
  */
 auth_payload_t *auth_payload_create(void);
 
-
-#endif /* AUTH_PAYLOAD_H_ */
+#endif /* AUTH_PAYLOAD_H_ @} */
index c456f4936435c398f62253bbea536ba2537b2e34..e641cfb0eafe015b2d70e9da9dcf2d67c754f8df 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file cert_payload.c
- * 
- * @brief Implementation of cert_payload_t.
- * 
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * WITHOUT ANY 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 <stddef.h>
 
-#include "cert_payload.h"
+#include <daemon.h>
 
+#include "cert_payload.h"
 
-ENUM(cert_encoding_names, CERT_NONE, CERT_OCSP_CONTENT,
-       "CERT_NONE",
-       "CERT_PKCS7_WRAPPED_X509",
-       "CERT_PGP",
-       "CERT_DNS_SIGNED_KEY",
-       "CERT_X509_SIGNATURE",
-       "CERT_X509_KEY_EXCHANGE",
-       "CERT_KERBEROS_TOKENS",
-       "CERT_CRL",
-       "CERT_ARL",
-       "CERT_SPKI",
-       "CERT_X509_ATTRIBUTE",
-       "CERT_RAW_RSA_KEY",
-       "CERT_X509_HASH_AND_URL",
-       "CERT_X509_HASH_AND_URL_BUNDLE",
-       "CERT_OCSP_CONTENT",
+ENUM(cert_encoding_names, ENC_PKCS7_WRAPPED_X509, ENC_OCSP_CONTENT,
+       "ENC_PKCS7_WRAPPED_X509",
+       "ENC_PGP",
+       "ENC_DNS_SIGNED_KEY",
+       "ENC_X509_SIGNATURE",
+       "ENC_X509_KEY_EXCHANGE",
+       "ENC_KERBEROS_TOKENS",
+       "ENC_CRL",
+       "ENC_ARL",
+       "ENC_SPKI",
+       "ENC_X509_ATTRIBUTE",
+       "ENC_RAW_RSA_KEY",
+       "ENC_X509_HASH_AND_URL",
+       "ENC_X509_HASH_AND_URL_BUNDLE",
+       "ENC_OCSP_CONTENT",
 );
 
 typedef struct private_cert_payload_t private_cert_payload_t;
@@ -74,12 +69,12 @@ struct private_cert_payload_t {
        /**
         * Encoding of the CERT Data.
         */
-       u_int8_t cert_encoding;
+       u_int8_t encoding;
        
        /**
         * The contained cert data value.
         */
-       chunk_t cert_data;
+       chunk_t data;
 };
 
 /**
@@ -105,9 +100,9 @@ encoding_rule_t cert_payload_encodings[] = {
        /* Length of the whole payload*/
        { PAYLOAD_LENGTH,       offsetof(private_cert_payload_t, payload_length)},
        /* 1 Byte CERT type*/
-       { U_INT_8,                      offsetof(private_cert_payload_t, cert_encoding) },
+       { U_INT_8,                      offsetof(private_cert_payload_t, encoding)              },
        /* some cert data bytes, length is defined in PAYLOAD_LENGTH */
-       { CERT_DATA,                    offsetof(private_cert_payload_t, cert_data) }
+       { CERT_DATA,            offsetof(private_cert_payload_t, data)                  }
 };
 
 /*
@@ -128,19 +123,14 @@ encoding_rule_t cert_payload_encodings[] = {
  */
 static status_t verify(private_cert_payload_t *this)
 {
-       if ((this->cert_encoding == 0) ||
-               ((this->cert_encoding >= CERT_ROOF) && (this->cert_encoding <= 200)))
-       {
-               /* reserved IDs */
-               return FAILED;
-       }
        return SUCCESS;
 }
 
 /**
  * Implementation of cert_payload_t.get_encoding_rules.
  */
-static void get_encoding_rules(private_cert_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
+static void get_encoding_rules(private_cert_payload_t *this,
+                                                          encoding_rule_t **rules, size_t *rule_count)
 {
        *rules = cert_payload_encodings;
        *rule_count = sizeof(cert_payload_encodings) / sizeof(encoding_rule_t);
@@ -159,7 +149,7 @@ static payload_type_t get_payload_type(private_cert_payload_t *this)
  */
 static payload_type_t get_next_type(private_cert_payload_t *this)
 {
-       return (this->next_payload);
+       return this->next_payload;
 }
 
 /**
@@ -179,56 +169,37 @@ static size_t get_length(private_cert_payload_t *this)
 }
 
 /**
- * Implementation of cert_payload_t.set_cert_encoding.
- */
-static void set_cert_encoding (private_cert_payload_t *this, cert_encoding_t encoding)
-{
-       this->cert_encoding = encoding;
-}
-
-/**
- * Implementation of cert_payload_t.get_cert_encoding.
- */
-static cert_encoding_t get_cert_encoding (private_cert_payload_t *this)
-{
-       return (this->cert_encoding);
-}
-
-/**
- * Implementation of cert_payload_t.set_data.
+ * Implementation of cert_payload_t.get_cert.
  */
-static void set_data (private_cert_payload_t *this, chunk_t data)
+static certificate_t* get_cert(private_cert_payload_t *this)
 {
-       if (this->cert_data.ptr != NULL)
-       {
-               chunk_free(&(this->cert_data));
-       }
-       this->cert_data.ptr = clalloc(data.ptr,data.len);
-       this->cert_data.len = data.len;
-       this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->cert_data.len;
-}
-
-/**
- * Implementation of cert_payload_t.get_data.
- */
-static chunk_t get_data (private_cert_payload_t *this)
-{
-       return (this->cert_data);
-}
-
-/**
- * Implementation of cert_payload_t.get_data_clone.
- */
-static chunk_t get_data_clone (private_cert_payload_t *this)
-{
-       chunk_t cloned_data;
-       if (this->cert_data.ptr == NULL)
+       certificate_type_t type;
+       
+       switch (this->encoding)
        {
-               return (this->cert_data);
+               case ENC_X509_SIGNATURE:
+                       type = CERT_X509;
+                       break;
+               case ENC_PKCS7_WRAPPED_X509:
+               case ENC_PGP:
+               case ENC_DNS_SIGNED_KEY:
+               case ENC_KERBEROS_TOKEN:
+               case ENC_CRL:
+               case ENC_ARL:
+               case ENC_SPKI:
+               case ENC_X509_ATTRIBUTE:
+               case ENC_RAW_RSA_KEY:
+               case ENC_X509_HASH_AND_URL:
+               case ENC_X509_HASH_AND_URL_BUNDLE:
+               case ENC_OCSP_CONTENT:
+               default:
+                       DBG1(DBG_ENC, "certificate encoding %N not supported",
+                                cert_encoding_names, this->encoding);
+                       return NULL;
        }
-       cloned_data.ptr = clalloc(this->cert_data.ptr,this->cert_data.len);
-       cloned_data.len = this->cert_data.len;
-       return cloned_data;
+       return lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
+                                                         BUILD_BLOB_ASN1_DER, chunk_clone(this->data),
+                                                         BUILD_END);
 }
 
 /**
@@ -236,11 +207,7 @@ static chunk_t get_data_clone (private_cert_payload_t *this)
  */
 static void destroy(private_cert_payload_t *this)
 {
-       if (this->cert_data.ptr != NULL)
-       {
-               chunk_free(&(this->cert_data));
-       }
-       
+       chunk_free(&this->data);
        free(this);     
 }
 
@@ -251,7 +218,6 @@ cert_payload_t *cert_payload_create()
 {
        private_cert_payload_t *this = malloc_thing(private_cert_payload_t);
 
-       /* interface functions */
        this->public.payload_interface.verify = (status_t (*) (payload_t*))verify;
        this->public.payload_interface.get_encoding_rules = (void (*) (payload_t*,encoding_rule_t**, size_t*))get_encoding_rules;
        this->public.payload_interface.get_length = (size_t (*) (payload_t*))get_length;
@@ -260,31 +226,38 @@ cert_payload_t *cert_payload_create()
        this->public.payload_interface.get_type = (payload_type_t (*) (payload_t*))get_payload_type;
        this->public.payload_interface.destroy = (void (*) (payload_t*))destroy;
        
-       /* public functions */
        this->public.destroy = (void (*) (cert_payload_t*))destroy;
-       this->public.set_cert_encoding = (void (*) (cert_payload_t*,cert_encoding_t))set_cert_encoding;
-       this->public.get_cert_encoding = (cert_encoding_t (*) (cert_payload_t*))get_cert_encoding;
-       this->public.set_data = (void (*) (cert_payload_t*,chunk_t))set_data;
-       this->public.get_data_clone = (chunk_t (*) (cert_payload_t*))get_data_clone;
-       this->public.get_data = (chunk_t (*) (cert_payload_t*))get_data;
+       this->public.get_cert = (certificate_t* (*) (cert_payload_t*))get_cert;
        
-       /* private variables */
        this->critical = FALSE;
        this->next_payload = NO_PAYLOAD;
        this->payload_length = CERT_PAYLOAD_HEADER_LENGTH;
-       this->cert_data = chunk_empty;
+       this->data = chunk_empty;
+       this->encoding = 0;
 
-       return (&(this->public));
+       return &this->public;
 }
 
 /*
  * Described in header
  */
-cert_payload_t *cert_payload_create_from_x509(x509_t *cert)
+cert_payload_t *cert_payload_create_from_cert(certificate_t *cert)
 {
-       cert_payload_t *this = cert_payload_create();
+       private_cert_payload_t *this = (private_cert_payload_t*)cert_payload_create();
 
-       this->set_cert_encoding(this, CERT_X509_SIGNATURE);
-       this->set_data(this, cert->get_certificate(cert));
-       return this;
+       switch (cert->get_type(cert))
+       {
+               case CERT_X509:
+                       this->encoding = ENC_X509_SIGNATURE;
+                       break;
+               default:
+                       DBG1(DBG_ENC, "embedding %N certificate in payload failed",
+                                certificate_type_names, cert->get_type(cert));
+                       free(this);
+                       return NULL;
+       }
+       this->data = cert->get_encoding(cert);
+       this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->data.len;
+       return &this->public;
 }
+
index bcb961398704c46172d1ebf21c5de15c19ace6c1..6b8228bb655a1f9e7a002b5264557c473487ca83 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file cert_payload.h
- * 
- * @brief Interface of cert_payload_t.
- * 
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * WITHOUT ANY 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 cert_payload cert_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef CERT_PAYLOAD_H_
 #define CERT_PAYLOAD_H_
 
-typedef enum cert_encoding_t cert_encoding_t;
 typedef struct cert_payload_t cert_payload_t;
+typedef enum cert_encoding_t cert_encoding_t;
 
 #include <library.h>
-#include <crypto/x509.h>
+#include <credentials/certificates/certificate.h>
 #include <encoding/payloads/payload.h>
 
 /**
  * Length of a cert payload without the cert data in bytes.
- * 
- * @ingroup payloads
  */
 #define CERT_PAYLOAD_HEADER_LENGTH 5
 
 /**
- * @brief Certificate encoding, as described in IKEv2 RFC section 3.6
- *
- * @ingroup payloads
+ * Certifcate encodings, as in RFC4306
  */
 enum cert_encoding_t {
-       CERT_NONE =                                              0,
-       CERT_PKCS7_WRAPPED_X509 =                1,
-       CERT_PGP =                                               2,
-       CERT_DNS_SIGNED_KEY =                    3,
-       CERT_X509_SIGNATURE =                    4,
-       CERT_KERBEROS_TOKEN     =                        6,
-       CERT_CRL =                                               7,
-       CERT_ARL =                                               8,
-       CERT_SPKI =                                              9,
-       CERT_X509_ATTRIBUTE =                   10,
-       CERT_RAW_RSA_KEY =                              11,
-       CERT_X509_HASH_AND_URL =                12,
-       CERT_X509_HASH_AND_URL_BUNDLE = 13,
-       CERT_OCSP_CONTENT =                             14,  /* from RFC 4806 */
-       CERT_ROOF =                                             15
+       ENC_PKCS7_WRAPPED_X509 =                 1,
+       ENC_PGP =                                                2,
+       ENC_DNS_SIGNED_KEY =                     3,
+       ENC_X509_SIGNATURE =                     4,
+       ENC_KERBEROS_TOKEN      =                        6,
+       ENC_CRL =                                                7,
+       ENC_ARL =                                                8,
+       ENC_SPKI =                                               9,
+       ENC_X509_ATTRIBUTE =                    10,
+       ENC_RAW_RSA_KEY =                               11,
+       ENC_X509_HASH_AND_URL =                 12,
+       ENC_X509_HASH_AND_URL_BUNDLE =  13,
+       ENC_OCSP_CONTENT =                              14,  /* from RFC 4806 */
 };
 
 /**
- * string mappings for cert_encoding_t.
- * 
- * @ingroup payloads
+ * Enum names for cert_encoding_t
  */
 extern enum_name_t *cert_encoding_names;
 
 /**
- * @brief Class representing an IKEv2 CERT payload.
+ * Class representing an IKEv2 CERT payload.
  *
  * The CERT payload format is described in RFC section 3.6.
- * This is just a dummy implementation to fullfill the standards
- * requirements. A full implementation would offer setters/getters
- * for the different encoding types.
- * 
- * @b Constructors:
- * - cert_payload_create()
- *
- * @todo Implement setters/getters for the different certificate encodings.
- *
- * @ingroup payloads
  */
 struct cert_payload_t {
        
@@ -89,78 +71,34 @@ struct cert_payload_t {
         * The payload_t interface.
         */
        payload_t payload_interface;
-
-       /**
-        * @brief Set the CERT encoding.
-        *
-        * @param this                  calling cert_payload_t object
-        * @param encoding              CERT encoding
-        */
-       void (*set_cert_encoding) (cert_payload_t *this, cert_encoding_t encoding);
-       
-       /**
-        * @brief Get the CERT encoding.
-        *
-        * @param this                  calling cert_payload_t object
-        * @return                              Encoding of the CERT 
-        */
-       cert_encoding_t (*get_cert_encoding) (cert_payload_t *this);
-       
-       /**
-        * @brief Set the CERT data.
-        * 
-        * Data are getting cloned.
-        *
-        * @param this                  calling cert_payload_t object
-        * @param data                  CERT data as chunk_t
-        */
-       void (*set_data) (cert_payload_t *this, chunk_t data);
        
        /**
-        * @brief Get the CERT data.
-        * 
-        * Returned data are a copy of the internal one.
+        * Get the playoads encoded certifcate.
         *
-        * @param this                  calling cert_payload_t object
-        * @return                              CERT data as chunk_t
+        * @return                              certifcate copy
         */
-       chunk_t (*get_data_clone) (cert_payload_t *this);
+       certificate_t *(*get_cert)(cert_payload_t *this);
        
        /**
-        * @brief Get the CERT data.
-        * 
-        * Returned data are NOT copied.
-        *
-        * @param this                  calling cert_payload_t object
-        * @return                              CERT data as chunk_t
-        */
-       chunk_t (*get_data) (cert_payload_t *this);
-       
-       /**
-        * @brief Destroys an cert_payload_t object.
-        *
-        * @param this                  cert_payload_t object to destroy
+        * Destroys the cert_payload object.
         */
        void (*destroy) (cert_payload_t *this);
 };
 
 /**
- * @brief Creates an empty cert_payload_t object.
+ * Creates an empty certificate payload.
  * 
+ * @param cert                         certificate to embed
  * @return                                     cert_payload_t object
- * 
- * @ingroup payloads
  */
 cert_payload_t *cert_payload_create(void);
 
 /**
- * @brief Creates a cert_payload_t object with an X.509 certificate.
+ * Creates a certificate payload with an embedded certificate.
  * 
- * @param cert                         X.509 certificate
+ * @param cert                         certificate to embed
  * @return                                     cert_payload_t object
- * 
- * @ingroup payloads
  */
-cert_payload_t *cert_payload_create_from_x509(x509_t *cert);
+cert_payload_t *cert_payload_create_from_cert(certificate_t *cert);
 
-#endif /* CERT_PAYLOAD_H_ */
+#endif /* CERT_PAYLOAD_H_ @} */
index 46663811aa104eaa001405dbe8b0725113d2580a..8e634243932072b094401cf1f224a751f7898b0b 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file certreq_payload.c
- * 
- * @brief Implementation of certreq_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 <stddef.h>
-#include <string.h>
 
 #include <daemon.h>
 #include <crypto/hashers/hasher.h>
-#include <crypto/ca.h>
+#include <encoding/payloads/cert_payload.h>
 
 #include "certreq_payload.h"
 
@@ -61,12 +55,12 @@ struct private_certreq_payload_t {
        /**
         * Encoding of the CERT Data.
         */
-       u_int8_t cert_encoding;
+       u_int8_t encoding;
        
        /**
         * The contained certreq data value.
         */
-       chunk_t certreq_data;
+       chunk_t data;
 };
 
 /**
@@ -90,11 +84,11 @@ encoding_rule_t certreq_payload_encodings[] = {
        { RESERVED_BIT, 0                                                                                                               },
        { RESERVED_BIT, 0                                                                                                               },
        /* Length of the whole payload*/
-       { PAYLOAD_LENGTH,       offsetof(private_certreq_payload_t, payload_length)},
+       { PAYLOAD_LENGTH,       offsetof(private_certreq_payload_t, payload_length)     },
        /* 1 Byte CERTREQ type*/
-       { U_INT_8,                      offsetof(private_certreq_payload_t, cert_encoding)},
+       { U_INT_8,                      offsetof(private_certreq_payload_t, encoding)           },
        /* some certreq data bytes, length is defined in PAYLOAD_LENGTH */
-       { CERTREQ_DATA,                 offsetof(private_certreq_payload_t, certreq_data)}
+       { CERTREQ_DATA,         offsetof(private_certreq_payload_t, data)                       }
 };
 
 /*
@@ -115,11 +109,15 @@ encoding_rule_t certreq_payload_encodings[] = {
  */
 static status_t verify(private_certreq_payload_t *this)
 {
-       if ((this->cert_encoding == 0) ||
-               ((this->cert_encoding >= CERT_ROOF) && (this->cert_encoding <= 200)))
+       if (this->encoding == ENC_X509_SIGNATURE)
        {
-               /* reserved IDs */
-               return FAILED;
+               if (this->data.len < HASH_SIZE_SHA1 ||
+                       this->data.len % HASH_SIZE_SHA1)
+               {
+                       DBG1(DBG_ENC, "invalid X509 hash length (%d) in certreq",
+                                this->data.len);
+                       return FAILED;
+               }
        }
        return SUCCESS;
 }
@@ -164,58 +162,78 @@ static size_t get_length(private_certreq_payload_t *this)
 {
        return this->payload_length;
 }
-
+       
 /**
- * Implementation of certreq_payload_t.set_cert_encoding.
+ * Implementation of certreq_payload_t.add_keyid.
  */
-static void set_cert_encoding (private_certreq_payload_t *this, cert_encoding_t encoding)
+static void add_keyid(private_certreq_payload_t *this, chunk_t keyid)
 {
-       this->cert_encoding = encoding;
+       this->data = chunk_cat("mc", this->data, keyid);
+       this->payload_length += keyid.len;
 }
 
+typedef struct keyid_enumerator_t keyid_enumerator_t;
+
 /**
- * Implementation of certreq_payload_t.get_cert_encoding.
+ * enumerator to enumerate keyids
  */
-static cert_encoding_t get_cert_encoding (private_certreq_payload_t *this)
-{
-       return (this->cert_encoding);
-}
+struct keyid_enumerator_t  {
+       enumerator_t public;
+       chunk_t full;
+       u_char *pos;
+};
 
 /**
- * Implementation of certreq_payload_t.set_data.
+ * enumerate function for keyid_enumerator
  */
-static void set_data (private_certreq_payload_t *this, chunk_t data)
+static bool keyid_enumerate(keyid_enumerator_t *this, chunk_t *chunk)
 {
-       if (this->certreq_data.ptr != NULL)
+       if (this->pos == NULL)
+       {
+               this->pos = this->full.ptr;
+       }
+       else
        {
-               chunk_free(&(this->certreq_data));
+               this->pos += HASH_SIZE_SHA1;
+               if (this->pos > (this->full.ptr + this->full.len - HASH_SIZE_SHA1))
+               {
+                       this->pos = NULL;
+               }
        }
-       this->certreq_data.ptr = clalloc(data.ptr,data.len);
-       this->certreq_data.len = data.len;
-       this->payload_length = CERTREQ_PAYLOAD_HEADER_LENGTH + this->certreq_data.len;
+       if (this->pos)
+       {
+               chunk->ptr = this->pos;
+               chunk->len = HASH_SIZE_SHA1;
+               return TRUE;
+       }
+       return FALSE;
 }
 
 /**
- * Implementation of certreq_payload_t.get_data.
+ * Implementation of certreq_payload_t.create_keyid_enumerator.
  */
-static chunk_t get_data (private_certreq_payload_t *this)
+static enumerator_t* create_keyid_enumerator(private_certreq_payload_t *this)
 {
-       return (this->certreq_data);
+       keyid_enumerator_t *enumerator = malloc_thing(keyid_enumerator_t);
+       enumerator->public.enumerate = (void*)keyid_enumerate;
+       enumerator->public.destroy = (void*)free;
+       enumerator->full = this->data;
+       enumerator->pos = NULL;
+       return &enumerator->public;
 }
 
 /**
- * Implementation of certreq_payload_t.get_data_clone.
+ * Implementation of certreq_payload_t.get_cert_type.
  */
-static chunk_t get_data_clone (private_certreq_payload_t *this)
+static certificate_type_t get_cert_type(private_certreq_payload_t *this)
 {
-       chunk_t cloned_data;
-       if (this->certreq_data.ptr == NULL)
+       switch (this->encoding)
        {
-               return (this->certreq_data);
+               case ENC_X509_SIGNATURE:
+                       return CERT_X509;
+               default:
+                       return CERT_ANY;
        }
-       cloned_data.ptr = clalloc(this->certreq_data.ptr,this->certreq_data.len);
-       cloned_data.len = this->certreq_data.len;
-       return cloned_data;
 }
 
 /**
@@ -223,11 +241,7 @@ static chunk_t get_data_clone (private_certreq_payload_t *this)
  */
 static void destroy(private_certreq_payload_t *this)
 {
-       if (this->certreq_data.ptr != NULL)
-       {
-               chunk_free(&(this->certreq_data));
-       }
-       
+       chunk_free(&this->data);
        free(this);     
 }
 
@@ -249,87 +263,38 @@ certreq_payload_t *certreq_payload_create()
        
        /* public functions */
        this->public.destroy = (void (*) (certreq_payload_t*)) destroy;
-       this->public.set_cert_encoding = (void (*) (certreq_payload_t*,cert_encoding_t))set_cert_encoding;
-       this->public.get_cert_encoding = (cert_encoding_t (*) (certreq_payload_t*))get_cert_encoding;
-       this->public.set_data = (void (*) (certreq_payload_t*,chunk_t))set_data;
-       this->public.get_data_clone = (chunk_t (*) (certreq_payload_t*))get_data_clone;
-       this->public.get_data = (chunk_t (*) (certreq_payload_t*))get_data;
+       this->public.create_keyid_enumerator = (enumerator_t*(*)(certreq_payload_t*))create_keyid_enumerator;
+               this->public.get_cert_type = (certificate_type_t(*)(certreq_payload_t*))get_cert_type;
+       this->public.add_keyid = (void(*)(certreq_payload_t*, chunk_t keyid))add_keyid;
        
        /* private variables */
        this->critical = FALSE;
        this->next_payload = NO_PAYLOAD;
-       this->payload_length =CERTREQ_PAYLOAD_HEADER_LENGTH;
-       this->certreq_data = chunk_empty;
+       this->payload_length = CERTREQ_PAYLOAD_HEADER_LENGTH;
+       this->data = chunk_empty;
+       this->encoding = 0;
 
-       return (&(this->public));
+       return &this->public;
 }
 
 /*
  * Described in header
  */
-certreq_payload_t *certreq_payload_create_from_cacert(identification_t *id)
+certreq_payload_t *certreq_payload_create_type(certificate_type_t type)
 {
-       x509_t *cacert;
-       rsa_public_key_t *pubkey;
-       chunk_t keyid;
-       certreq_payload_t *this;
+       private_certreq_payload_t *this = (private_certreq_payload_t*)certreq_payload_create();
        
-       cacert = charon->credentials->get_auth_certificate(charon->credentials, AUTH_CA, id);
-       if (cacert == NULL)
+       switch (type)
        {
-               /* no such CA cert */
-               return NULL;
+               case CERT_X509:
+                       this->encoding = ENC_X509_SIGNATURE;
+                       break;
+               default:
+                       DBG1(DBG_ENC, "certificate type %N not supported in requests",
+                                certificate_type_names, type);
+                       free(this);
+                       return NULL;
        }
-
-       this = certreq_payload_create();
-       pubkey = cacert->get_public_key(cacert);
-       keyid = pubkey->get_keyid(pubkey);
-
-       DBG2(DBG_IKE, "requesting certificate issued by '%D'", id);
-       DBG2(DBG_IKE, "  with keyid %#B", &keyid);
-
-       this->set_cert_encoding(this, CERT_X509_SIGNATURE);
-       this->set_data(this, keyid);
-       return this;
+       return &this->public;
 }
 
-/*
- * Described in header
- */
-certreq_payload_t *certreq_payload_create_from_cacerts(void)
-{
-       certreq_payload_t *this;
-       chunk_t keyids;
-       u_char *pos;
-       ca_info_t *cainfo;
-
-       iterator_t *iterator = charon->credentials->create_cainfo_iterator(charon->credentials);
-       int count = iterator->get_count(iterator);
-
-       if (count == 0)
-       {
-               iterator->destroy(iterator);
-               return NULL;
-       }
-
-       this = certreq_payload_create();
-       keyids = chunk_alloc(count * HASH_SIZE_SHA1);
-       pos = keyids.ptr;
-
-       while (iterator->iterate(iterator, (void**)&cainfo))
-       {
-               x509_t *cacert = cainfo->get_certificate(cainfo);
-               chunk_t keyid = cacert->get_keyid(cacert);
-
-               DBG2(DBG_IKE, "requesting certificate issued by '%D'", cacert->get_subject(cacert));
-               DBG2(DBG_IKE, "  with keyid %#B", &keyid);
-               memcpy(pos, keyid.ptr, keyid.len);
-               pos += HASH_SIZE_SHA1;
-       }
-       iterator->destroy(iterator);
-
-       this->set_cert_encoding(this, CERT_X509_SIGNATURE);
-       this->set_data(this, keyids);
-       free(keyids.ptr);
-       return this;
-}
index 2985fdae144f17746010cb37f5030f502e49d21c..9ef4fb9d9dc90c4f9b289031fd1236ccf75f5fa0 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file certreq_payload.h
- * 
- * @brief Interface of certreq_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 certreq_payload certreq_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef CERTREQ_PAYLOAD_H_
@@ -32,26 +32,13 @@ typedef struct certreq_payload_t certreq_payload_t;
 
 /**
  * Length of a CERTREQ payload without the CERTREQ data in bytes.
- * 
- * @ingroup payloads
  */
 #define CERTREQ_PAYLOAD_HEADER_LENGTH 5
 
-
 /**
- * @brief Class representing an IKEv2 CERTREQ payload.
+ * Class representing an IKEv2 CERTREQ payload.
  *
  * The CERTREQ payload format is described in RFC section 3.7.
- * This is just a dummy implementation to fullfill the standards
- * requirements. A full implementation would offer setters/getters
- * for the different encoding types.
- *
- * @b Constructors:
- * - certreq_payload_create()
- *
- * @todo Implement payload functionality.
- *
- * @ingroup payloads
  */
 struct certreq_payload_t {
        /**
@@ -60,85 +47,46 @@ struct certreq_payload_t {
        payload_t payload_interface;
 
        /**
-        * @brief Set the CERT encoding.
-        *
-        * @param this                  calling certreq_payload_t object
-        * @param encoding              CERT encoding
-        */
-       void (*set_cert_encoding) (certreq_payload_t *this, cert_encoding_t encoding);
-       
-       /**
-        * @brief Get the CERT encoding.
-        *
-        * @param this                  calling certreq_payload_t object
-        * @return                              Encoding of the CERT 
-        */
-       cert_encoding_t (*get_cert_encoding) (certreq_payload_t *this);
-       
-       /**
-        * @brief Set the CERTREQ data.
-        * 
-        * Data are getting cloned.
+        * Create an enumerator over contained keyids.
         *
-        * @param this                  calling certreq_payload_t object
-        * @param data                  CERTREQ data as chunk_t
+        * @return                      enumerator over chunk_t's.
         */
-       void (*set_data) (certreq_payload_t *this, chunk_t data);
+       enumerator_t* (*create_keyid_enumerator)(certreq_payload_t *this);
        
        /**
-        * @brief Get the CERTREQ data.
-        * 
-        * Returned data are a copy of the internal one.
+        * Get the type of contained certificate keyids.
         *
-        * @param this                  calling certreq_payload_t object
-        * @return                              CERTREQ data as chunk_t
+        * @return                      certificate keyid type
         */
-       chunk_t (*get_data_clone) (certreq_payload_t *this);
+       certificate_type_t (*get_cert_type)(certreq_payload_t *this);
        
        /**
-        * @brief Get the CERTREQ data.
-        * 
-        * Returned data are NOT copied.
+        * Add a certificates keyid to the payload.
         *
-        * @param this                  calling certreq_payload_t object
-        * @return                              CERTREQ data as chunk_t
+        * @param keyid         keyid of the trusted certifcate
+        * @return
         */
-       chunk_t (*get_data) (certreq_payload_t *this);
+       void (*add_keyid)(certreq_payload_t *this, chunk_t keyid);
        
        /**
-        * @brief Destroys an certreq_payload_t object.
-        *
-        * @param this  certreq_payload_t object to destroy
+        * Destroys an certreq_payload_t object.
         */
        void (*destroy) (certreq_payload_t *this);
 };
 
 /**
- * @brief Creates an empty certreq_payload_t object.
+ * Creates an empty certreq_payload_t object.
  * 
- * @return certreq_payload_t object
- * 
- * @ingroup payloads
+ * @return                             certreq payload
  */
 certreq_payload_t *certreq_payload_create(void);
 
 /**
- * @brief Creates a certreq_payload_t object from a ca certificate
- * 
- * @param id                           subject distinguished name of CA certificate
- * @return                                     certreq_payload_t object
- * 
- * @ingroup payloads
- */
-certreq_payload_t *certreq_payload_create_from_cacert(identification_t *id);
-
-/**
- * @brief Creates a certreq_payload_t object from all ca certificates
- * 
- * @return                                     certreq_payload_t object
+ * Creates an empty certreq_payload_t for a kind of certificates.
  * 
- * @ingroup payloads
+ * @param type                 type of the added keyids
+ * @return                             certreq payload
  */
-certreq_payload_t *certreq_payload_create_from_cacerts(void);
+certreq_payload_t *certreq_payload_create_type(certificate_type_t type);
 
-#endif /* CERTREQ_PAYLOAD_H_ */
+#endif /* CERTREQ_PAYLOAD_H_ @} */
index afd08c6beacf0a8cbbbd4c598c25e35022bfdc27..1d0c0092648e4ebcde0cbb09db73efc3983a7673 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file configuration_attribute.c
- * 
- * @brief Implementation of configuration_attribute_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 5c4f65b1432295aa86c650d2c604b1c642263d64..15123736060a7661a349c28e1f9a5f309d4538a6 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file configuration_attribute.h
- * 
- * @brief Interface of configuration_attribute_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 configuration_attribute configuration_attribute
+ * @{ @ingroup payloads
  */
 
 #ifndef CONFIGURATION_ATTRIBUTE_H_
@@ -33,15 +33,11 @@ typedef struct configuration_attribute_t configuration_attribute_t;
 
 /**
  * Configuration attribute header length in bytes.
- * 
- * @ingroup payloads
  */
 #define CONFIGURATION_ATTRIBUTE_HEADER_LENGTH 4
 
 /**
  * Type of the attribute, as in IKEv2 RFC 3.15.1.
- * 
- * @ingroup payloads
  */
 enum configuration_attribute_type_t {
        INTERNAL_IP4_ADDRESS = 1,
@@ -62,20 +58,13 @@ enum configuration_attribute_type_t {
 
 /** 
  * enum names for configuration_attribute_type_t.
- * 
- * @ingroup payloads
  */
 extern enum_name_t *configuration_attribute_type_names;
 
 /**
- * @brief Class representing an IKEv2-CONFIGURATION Attribute.
+ * Class representing an IKEv2-CONFIGURATION Attribute.
  * 
  * The CONFIGURATION ATTRIBUTE format is described in RFC section 3.15.1.
- * 
- * @b Constructors:
- * - configuration_attribute_create()
- * 
- * @ingroup payloads
  */
 struct configuration_attribute_t {
        /**
@@ -84,64 +73,55 @@ struct configuration_attribute_t {
        payload_t payload_interface;
 
        /**
-        * @brief Returns the currently set value of the attribute.
+        * Returns the currently set value of the attribute.
         *      
         * @warning Returned data are not copied.
         * 
-        * @param this  calling configuration_attribute_t object
         * @return              chunk_t pointing to the value
         */
        chunk_t (*get_value) (configuration_attribute_t *this);
        
        /**
-        * @brief Sets the value of the attribute.
+        * Sets the value of the attribute.
         *      
-        * @warning Value is getting copied.
+        * Value is getting copied.
         * 
-        * @param this  calling configuration_attribute_t object
         * @param value chunk_t pointing to the value to set
         */
        void (*set_value) (configuration_attribute_t *this, chunk_t value);
 
        /**
-        * @brief Sets the type of the attribute.
+        * Sets the type of the attribute.
         *      
-        * @param this  calling configuration_attribute_t object
         * @param type  type to set (most significant bit is set to zero)
         */
        void (*set_type) (configuration_attribute_t *this, u_int16_t type);
        
        /**
-        * @brief get the type of the attribute.
+        * get the type of the attribute.
         *      
-        * @param this  calling configuration_attribute_t object
         * @return              type of the value
         */
        u_int16_t (*get_type) (configuration_attribute_t *this);
        
        /**
-        * @brief get the length of an attribute.
+        * get the length of an attribute.
         *      
-        * @param this  calling configuration_attribute_t object
         * @return              type of the value
         */
        u_int16_t (*get_length) (configuration_attribute_t *this);
        
        /**
-        * @brief Destroys an configuration_attribute_t object.
-        *
-        * @param this  configuration_attribute_t object to destroy
+        * Destroys an configuration_attribute_t object.
         */
        void (*destroy) (configuration_attribute_t *this);
 };
 
 /**
- * @brief Creates an empty configuration_attribute_t object.
+ * Creates an empty configuration_attribute_t object.
  * 
  * @return                     created configuration_attribute_t object
- * 
- * @ingroup payloads
  */
 configuration_attribute_t *configuration_attribute_create(void);
 
-#endif /* CONFIGURATION_ATTRIBUTE_H_*/
+#endif /* CONFIGURATION_ATTRIBUTE_H_ @} */
index 380ed9681341db591f9412d61c7ffcd1483e5aee..844182a5f373ff2bcf11f3d3110d8d62240e5ed9 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file cp_payload.c
- * 
- * @brief Implementation of cp_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 27ff41005bd127f6ff39fc9bc8b69044fb65e6f9..d2e94197c32792da81961b301e6d6fff0212f470 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file cp_payload.h
- * 
- * @brief Interface of cp_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 cp_payload cp_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef CP_PAYLOAD_H_
@@ -34,15 +34,11 @@ typedef struct cp_payload_t cp_payload_t;
 
 /**
  * CP_PAYLOAD length in bytes without any proposal substructure.
- * 
- * @ingroup payloads
  */
 #define CP_PAYLOAD_HEADER_LENGTH 8
 
 /**
  * Config Type of an Configuration Payload.
- *
- * @ingroup payloads
  */
 enum config_type_t {
        CFG_REQUEST = 1,
@@ -53,20 +49,13 @@ enum config_type_t {
 
 /**
  * enum name for config_type_t.
- *
- * @ingroup payloads
  */
 extern enum_name_t *config_type_names;
 
 /**
- * @brief Class representing an IKEv2-CP Payload.
+ * Class representing an IKEv2-CP Payload.
  * 
  * The CP Payload format is described in RFC section 3.15.
- * 
- * @b Constructors:
- * - cp_payload_create()
- * 
- * @ingroup payloads
  */
 struct cp_payload_t {
        /**
@@ -75,58 +64,50 @@ struct cp_payload_t {
        payload_t payload_interface;
        
        /**
-        * @brief Creates an iterator of stored configuration_attribute_t objects.
+        * Creates an iterator of stored configuration_attribute_t objects.
         * 
         * When deleting an attribute using this iterator, the length of this
         * configuration_attribute_t has to be refreshed by calling get_length()!
         *
-        * @param this                  calling cp_payload_t object
         * @return                              created iterator_t object
         */
        iterator_t *(*create_attribute_iterator) (cp_payload_t *this);
        
        /**
-        * @brief Adds a configuration_attribute_t object to this object.
+        * Adds a configuration_attribute_t object to this object.
         * 
         * The added configuration_attribute_t object is getting destroyed in
         * destroy function of cp_payload_t.
         *
-        * @param this                  calling cp_payload_t object
         * @param attribute             configuration_attribute_t object to add
         */
        void (*add_configuration_attribute) (cp_payload_t *this, configuration_attribute_t *attribute);
        
        /**
-        * @brief Set the config type.
+        * Set the config type.
         *
-        * @param this                  calling cp_payload_t object
         * @param config_type   config_type_t to set
         */
        void (*set_config_type) (cp_payload_t *this,config_type_t config_type);
        
        /**
-        * @brief Get the config type.
+        * Get the config type.
         *
-        * @param this                  calling cp_payload_t object
         * @return                              config_type_t
         */
        config_type_t (*get_config_type) (cp_payload_t *this);
        
        /**
-        * @brief Destroys an cp_payload_t object.
-        *
-        * @param this                  cp_payload_t object to destroy
+        * Destroys an cp_payload_t object.
         */
        void (*destroy) (cp_payload_t *this);
 };
 
 /**
- * @brief Creates an empty cp_payload_t object
+ * Creates an empty cp_payload_t object
  * 
  * @return cp_payload_t object
- * 
- * @ingroup payloads
  */
 cp_payload_t *cp_payload_create(void);
 
-#endif /*CP_PAYLOAD_H_*/
+#endif /*CP_PAYLOAD_H_ @} */
index 1d42a3af2ffbae61e9895e6bdf0c70e041c3d4c4..928e6523abef0f603e641019f8a5a0dfc6a51155 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file delete_payload.c
- * 
- * @brief Implementation of delete_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 508f7fba24919e5b00ed9f4ea258340572833d08..150a8747052940b901e1a942c37d15fc3d640a62 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file delete_payload.h
- * 
- * @brief Interface of delete_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 delete_payload delete_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef DELETE_PAYLOAD_H_
@@ -32,22 +32,13 @@ typedef struct delete_payload_t delete_payload_t;
 
 /**
  * Length of a delete payload without the SPI in bytes.
- *
- * @ingroup payloads
  */
 #define DELETE_PAYLOAD_HEADER_LENGTH 8
 
 /**
- * @brief Class representing an IKEv2 DELETE payload.
+ * Class representing an IKEv2 DELETE payload.
  *
  * The DELETE payload format is described in RFC section 3.11.
- *
- * @b Constructors:
- * - delete_payload_create()
- *
- * @todo Implement better setter/getters
- *
- * @ingroup payloads
  */
 struct delete_payload_t {
        /**
@@ -56,47 +47,40 @@ struct delete_payload_t {
        payload_t payload_interface;
        
        /**
-        * @brief Get the protocol ID.
+        * Get the protocol ID.
         *
-        * @param this                  calling delete_payload_t object
         * @return                              protocol ID
         */
        protocol_id_t (*get_protocol_id) (delete_payload_t *this);
        
        /**
-        * @brief Add an SPI to the list of deleted SAs.
+        * Add an SPI to the list of deleted SAs.
         *
-        * @param this                  calling delete_payload_t object
         * @param spi                   spi to add
         */
        void (*add_spi) (delete_payload_t *this, u_int32_t spi);
        
        /**
-        * @brief Get an iterator over the SPIs.
+        * Get an iterator over the SPIs.
         *
         * The iterate() function returns a pointer to a u_int32_t SPI.
         *
-        * @param this                  calling delete_payload_t object
         * @return                              iterator over SPIs
         */
        iterator_t *(*create_spi_iterator) (delete_payload_t *this);
        
        /**
-        * @brief Destroys an delete_payload_t object.
-        *
-        * @param this  delete_payload_t object to destroy
+        * Destroys an delete_payload_t object.
         */
        void (*destroy) (delete_payload_t *this);
 };
 
 /**
- * @brief Creates an empty delete_payload_t object.
+ * Creates an empty delete_payload_t object.
  * 
  * @param protocol_id  protocol, such as AH|ESP
  * @return                             delete_payload_t object
- * 
- * @ingroup payloads
  */
 delete_payload_t *delete_payload_create(protocol_id_t protocol_id);
 
-#endif /* DELETE_PAYLOAD_H_ */
+#endif /* DELETE_PAYLOAD_H_ @} */
index da2498c5e67ec37483910fece1b283338ec90ea6..551c908c672210b71406518336b3ee31fa849010 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_payload.c
- * 
- * @brief Implementation of eap_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index e4f8663c26b4bc0bad17ba37913aae59732f8b8a..fe723ef633b152139406b04e505a286ed6aa7c57 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_payload.h
- * 
- * @brief Interface of eap_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 eap_payload eap_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef EAP_PAYLOAD_H_
@@ -32,20 +32,13 @@ typedef struct eap_payload_t eap_payload_t;
 
 /**
  * Length of a EAP payload without the EAP Message in bytes.
- * 
- * @ingroup payloads
  */
 #define EAP_PAYLOAD_HEADER_LENGTH 4
 
 /**
- * @brief Class representing an IKEv2 EAP payload.
+ * Class representing an IKEv2 EAP payload.
  *
  * The EAP payload format is described in RFC section 3.16.
- * 
- * @b Constructors:
- * - eap_payload_create()
- *
- * @ingroup payloads
  */
 struct eap_payload_t {
        
@@ -55,79 +48,68 @@ struct eap_payload_t {
        payload_t payload_interface;
        
        /**
-        * @brief Set the contained EAP data.
+        * Set the contained EAP data.
         *
         * This contains the FULL EAP message starting with "code".
         * Chunk gets cloned.
         *
-        * @param this          calling eap_payload_t object
         * @param message       EAP data
         */
        void (*set_data) (eap_payload_t *this, chunk_t data);
        
        /**
-        * @brief Get the contained EAP data.
+        * Get the contained EAP data.
         *
         * This contains the FULL EAP message starting with "code".
         *
-        * @param this          calling eap_payload_t object
         * @return                      EAP data (pointer to internal data)
         */
        chunk_t (*get_data) (eap_payload_t *this);
        
        /**
-        * @brief Get the EAP code.
+        * Get the EAP code.
         *
-        * @param this          calling eap_payload_t object
         * @return                      EAP message as chunk_t
         */
        eap_code_t (*get_code) (eap_payload_t *this);
        
        /**
-        * @brief Get the EAP identifier.
+        * Get the EAP identifier.
         *
-        * @param this          calling eap_payload_t object
         * @return                      unique identifier
         */
        u_int8_t (*get_identifier) (eap_payload_t *this);
        
        /**
-        * @brief Get the EAP method type.
+        * Get the EAP method type.
         *
-        * @param this          calling eap_payload_t object
         * @param vendor        pointer receiving vendor identifier
         * @return                      EAP method type, vendor specific if vendor != 0
         */
        eap_type_t (*get_type) (eap_payload_t *this, u_int32_t *vendor);
        
        /**
-        * @brief Destroys an eap_payload_t object.
-        *
-        * @param this          eap_payload_t object to destroy
+        * Destroys an eap_payload_t object.
         */
        void (*destroy) (eap_payload_t *this);
 };
 
 /**
- * @brief Creates an empty eap_payload_t object.
+ * Creates an empty eap_payload_t object.
  *
  * @return eap_payload_t object
- *
- * @ingroup payloads
  */
 eap_payload_t *eap_payload_create(void);
 
 /**
- * @brief Creates an eap_payload_t object with data.
+ * Creates an eap_payload_t object with data.
  *
  * @return eap_payload_t object
- *
- * @ingroup payloads
  */
 eap_payload_t *eap_payload_create_data(chunk_t data);
 
 /**
- * @brief Creates an eap_payload_t object with a code.
+ * Creates an eap_payload_t object with a code.
  *
  * Could should be either EAP_SUCCESS/EAP_FAILURE, use 
  * constructor above otherwise.
@@ -135,19 +117,15 @@ eap_payload_t *eap_payload_create_data(chunk_t data);
  * @param code                 EAP status code
  * @param identifier   EAP identifier to use in payload
  * @return                             eap_payload_t object
- *
- * @ingroup payloads
  */
 eap_payload_t *eap_payload_create_code(eap_code_t code, u_int8_t identifier);
 
 /**
- * @brief Creates an eap_payload_t EAP_RESPONSE containing an EAP_NAK.
+ * Creates an eap_payload_t EAP_RESPONSE containing an EAP_NAK.
  *
  * @param identifier   EAP identifier to use in payload
  * @return                             eap_payload_t object
- *
- * @ingroup payloads
  */
 eap_payload_t *eap_payload_create_nak(u_int8_t identifier);
 
-#endif /* EAP_PAYLOAD_H_ */
+#endif /* EAP_PAYLOAD_H_ @} */
index 55a7cf132900a25557fe8880b11e67dcde828b37..7db9e189fae2b068ea29ceb83484031e5369adb9 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file encodings.c
- * 
- * @brief String mappings of encoding_type_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
+ *
+ * $Id$
  */
 
 
index 5e07fbfab0b35173d1f1cb854138e5db41329599..b4658e2852651e3eee6daf2f0f0a82a11fef9cdc 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file encodings.h
- * 
- * @brief Definition of encoding_type_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 encodings encodings
+ * @{ @ingroup payloads
  */
 
 #ifndef ENCODINGS_H_
@@ -30,7 +30,7 @@ typedef struct encoding_rule_t encoding_rule_t;
 #include <library.h>
 
 /**
- * @brief All different kinds of encoding types. 
+ * All different kinds of encoding types. 
  *
  * Each field of an IKEv2-Message (in header or payload) 
  * which has to be parsed or generated differently has its own
@@ -40,8 +40,6 @@ typedef struct encoding_rule_t encoding_rule_t;
  * from PRIVATE USE space. Also the substructures 
  * of specific payload types get their own payload_id 
  * from PRIVATE_USE space. See IKEv2-Draft for more informations.
- *
- * @ingroup payloads
  */
 enum encoding_type_t {
        
@@ -114,7 +112,7 @@ enum encoding_type_t {
        U_INT_64,
        
        /**
-        * @brief represents a RESERVED_BIT used in FLAG-Bytes.
+        * represents a RESERVED_BIT used in FLAG-Bytes.
         * 
         * When generating, the next bit is set to zero and the current write 
         * position is moved one bit forward.
@@ -128,7 +126,7 @@ enum encoding_type_t {
        RESERVED_BIT,
        
        /**
-        * @brief represents a RESERVED_BYTE.
+        * represents a RESERVED_BYTE.
         * 
         * When generating, the next byte is set to zero and the current write 
         * position is moved one byte forward.
@@ -499,21 +497,16 @@ enum encoding_type_t {
 
 /**
  * enum name for encoding_type_t
- * 
- * @ingroup payloads
  */
 extern enum_name_t *encoding_type_names;
 
 /**
+ * Rule how to en-/decode a payload field.
+ *
  * An encoding rule is a mapping of a specific encoding type to 
  * a location in the data struct where the current field is stored to
  * or read from.
- * 
- * For examples see files in this directory.
- * 
  * This rules are used by parser and generator.
- * 
- * @ingroup payloads
  */
 struct encoding_rule_t {
        
@@ -534,4 +527,4 @@ struct encoding_rule_t {
        u_int32_t offset;
 };
 
-#endif /*ENCODINGS_H_*/
+#endif /*ENCODINGS_H_ @} */
index 23b6e8d9fe5d40be96ec218e49b2d1b0c2ad7696..cdfda3d5e5ad4bbef1deee998290e75d2fdd8f75 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file encryption_payload.c
- * 
- * @brief Implementation of encryption_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 7cf53619fcefdb17f02b07241b120fa438ff9623..8170064095c4d2058e1de225b723e6c47411d0fe 100644 (file)
@@ -1,9 +1,3 @@
-/**
- * @file encryption_payload.h
- * 
- * @brief Interface of encryption_payload_t.
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 encryption_payload encryption_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef ENCRYPTION_PAYLOAD_H_
@@ -33,14 +34,12 @@ typedef struct encryption_payload_t encryption_payload_t;
 
 /**
  * Encrpytion payload length in bytes without IV and following data.
- * 
- * @ingroup payloads
  */
 #define ENCRYPTION_PAYLOAD_HEADER_LENGTH 4
 
 
 /**
- * @brief The encryption payload as described in RFC section 3.14.
+ * The encryption payload as described in RFC section 3.14.
  *
  * Before any crypt/decrypt/sign/verify operation can occur, 
  * the transforms must be set. After that, a parsed encryption payload
@@ -51,11 +50,6 @@ typedef struct encryption_payload_t encryption_payload_t;
  * must be builded after generation of all payloads and the encryption
  * of the encryption payload.
  * Signature verificatin is done before decryption.
- *
- * @b Constructors:
- * - encryption_payload_create()
- *
- * @ingroup payloads
  */
 struct encryption_payload_t {
        /**
@@ -64,29 +58,26 @@ struct encryption_payload_t {
        payload_t payload_interface;
        
        /**
-        * @brief Creates an iterator for all contained payloads.
+        * Creates an iterator for all contained payloads.
         * 
-        * @warning iterator_t object has to get destroyed by the caller.
+        * iterator_t object has to get destroyed by the caller.
         *
-        * @param this                  calling encryption_payload_t object
-        * @param[in] forward   iterator direction (TRUE: front to end)
+        * @param forward               iterator direction (TRUE: front to end)
         * return                               created iterator_t object
         */
         iterator_t *(*create_payload_iterator) (encryption_payload_t *this, bool forward);
        
        /**
-        * @brief Adds a payload to this encryption payload.
+        * Adds a payload to this encryption payload.
         *
-        * @param this                  calling encryption_payload_t object
         * @param payload               payload_t object to add
         */
        void (*add_payload) (encryption_payload_t *this, payload_t *payload);
        
        /**
-        * @brief Reove the last payload in the contained payload list.
+        * Reove the last payload in the contained payload list.
         *
-        * @param this                  calling encryption_payload_t object
-        * @param[out] payload  removed payload
+        * @param payload               removed payload
         * @return
         *                                              - SUCCESS, or
         *                                              - NOT_FOUND if list empty
@@ -94,15 +85,14 @@ struct encryption_payload_t {
        status_t (*remove_first_payload) (encryption_payload_t *this, payload_t **payload);
        
        /**
-        * @brief Get the number of payloads.
+        * Get the number of payloads.
         *
-        * @param this                  calling encryption_payload_t object
         * @return                              number of contained payloads
         */
        size_t (*get_payload_count) (encryption_payload_t *this);
        
        /**
-        * @brief Set transforms to use.
+        * Set transforms to use.
         * 
         * To decryption, encryption, signature building and verifying,
         * the payload needs a crypter and a signer object.
@@ -110,34 +100,29 @@ struct encryption_payload_t {
         * @warning Do NOT call this function again after encryption, since
         * the signer must be the same while encrypting and signature building!
         *
-        * @param this                  calling encryption_payload_t
         * @param crypter               crypter_t to use for data de-/encryption
         * @param signer                signer_t to use for data signing/verifying
         */
        void (*set_transforms) (encryption_payload_t *this, crypter_t *crypter, signer_t *signer);
        
        /**
-        * @brief Generate and encrypt contained payloads.
+        * Generate and encrypt contained payloads.
         * 
         * This function generates the content for added payloads
         * and encrypts them. Signature is not built, since we need
         * additional data (the full message).
         *
-        * @param this                  calling encryption_payload_t
-        * @return
-        *                                              - SUCCESS, or
-        *                                              - INVALID_STATE if transforms not set
+        * @return                              SUCCESS, or INVALID_STATE if transforms not set
         */
        status_t (*encrypt) (encryption_payload_t *this);
        
        /**
-        * @brief Decrypt and parse contained payloads.
+        * Decrypt and parse contained payloads.
         * 
         * This function decrypts the contained data. After, 
         * the payloads are parsed internally and are accessible
         * via the iterator.
         *
-        * @param this                  calling encryption_payload_t
         * @return
         *                                              - SUCCESS, or
         *                                              - INVALID_STATE if transforms not set, or
@@ -146,13 +131,12 @@ struct encryption_payload_t {
        status_t (*decrypt) (encryption_payload_t *this);
        
        /**
-        * @brief Build the signature.
+        * Build the signature.
         * 
         * The signature is built over the FULL message, so the header
         * and every payload (inclusive this one) must already be generated.
         * The generated message is supplied via the data paramater.
         * 
-        * @param this                  calling encryption_payload_t
         * @param data                  chunk contains the already generated message
         * @return
         *                                              - SUCCESS, or
@@ -161,13 +145,12 @@ struct encryption_payload_t {
        status_t (*build_signature) (encryption_payload_t *this, chunk_t data);
                
        /**
-        * @brief Verify the signature.
+        * Verify the signature.
         * 
         * Since the signature is built over the full message, we need
         * this data to do the verification. The message data
         * is supplied via the data argument.
         * 
-        * @param this                  calling encryption_payload_t
         * @param data                  chunk contains the message 
         * @return
         *                                              - SUCCESS, or
@@ -177,21 +160,16 @@ struct encryption_payload_t {
        status_t (*verify_signature) (encryption_payload_t *this, chunk_t data);
 
        /**
-        * @brief Destroys an encryption_payload_t object.
-        *
-        * @param this                  encryption_payload_t object to destroy
+        * Destroys an encryption_payload_t object.
         */
        void (*destroy) (encryption_payload_t *this);
 };
 
 /**
- * @brief Creates an empty encryption_payload_t object.
+ * Creates an empty encryption_payload_t object.
  * 
  * @return encryption_payload_t object
- * 
- * @ingroup payloads
  */
 encryption_payload_t *encryption_payload_create(void);
 
-
-#endif /*ENCRYPTION_PAYLOAD_H_*/
+#endif /*ENCRYPTION_PAYLOAD_H_ @} */
index 98bfb2ea0b1d621eb1a43e58bf1b070c7be92cdb..bef51a24919f311c87366c393cddc2394b801ade 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file endpoint_notify.c
- * 
- * @brief Implementation of endpoint_notify_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "endpoint_notify.h"
index 4a3a68f95bd87684393cd52449b63ec3d9589f8d..9203dc8ec6aa98ee2a0ff768ef126a73dec725a3 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file endpoint_notify.h
- * 
- * @brief Interface of endpoint_notify_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 endpoint_notify endpoint_notify
+ * @{ @ingroup payloads
+ */
 
 #ifndef ENDPOINT_NOTIFY_H_
 #define ENDPOINT_NOTIFY_H_
@@ -36,9 +35,7 @@ typedef struct endpoint_notify_t endpoint_notify_t;
 #include <encoding/payloads/notify_payload.h>
 
 /**
- * @brief P2P endpoint families.
- *
- * @ingroup payloads
+ * P2P endpoint families.
  */
 enum p2p_endpoint_family_t {
        
@@ -53,9 +50,7 @@ enum p2p_endpoint_family_t {
 };
 
 /**
- * @brief P2P endpoint types.
- *
-  * @ingroup payloads
+ * P2P endpoint types.
  */
 enum p2p_endpoint_type_t {
        
@@ -75,128 +70,106 @@ enum p2p_endpoint_type_t {
 
 /**
  * enum name for p2p_endpoint_type_t.
- *
- * @ingroup payloads
  */
 extern enum_name_t *p2p_endpoint_type_names;
 
 /**
- * @brief Class representing a P2P_ENDPOINT notify. In fact it's not
+ * Class representing a P2P_ENDPOINT notify. In fact it's not
  * the notify per se, but the notification data of that notify that is
  * handled with this class.
- * 
- * @b Constructors:
- * - endpoint_notify_create()
- * - endpoint_notify_create_from_host()
- *
- * @ingroup payloads
  */
 struct endpoint_notify_t {
        /**
-        * @brief Returns the priority of this endpoint.
+        * Returns the priority of this endpoint.
         * 
-        * @param this          object
         * @return                      priority
         */
        u_int32_t (*get_priority) (endpoint_notify_t *this);
        
        /**
-        * @brief Sets the priority of this endpoint.
+        * Sets the priority of this endpoint.
         * 
-        * @param this          object
         * @param priority      priority
         */
        void (*set_priority) (endpoint_notify_t *this, u_int32_t priority);
        
        /**
-        * @brief Returns the endpoint type of this endpoint.
+        * Returns the endpoint type of this endpoint.
         * 
-        * @param this          object
         * @return                      endpoint type
         */
        p2p_endpoint_type_t (*get_type) (endpoint_notify_t *this);
        
        /**
-        * @brief Returns the endpoint family of this endpoint.
+        * Returns the endpoint family of this endpoint.
         * 
-        * @param this          object
         * @return                      endpoint family
         */
        p2p_endpoint_family_t (*get_family) (endpoint_notify_t *this);
        
        /**
-        * @brief Returns the host of this endpoint.
+        * Returns the host of this endpoint.
         * 
-        * @param this          object
         * @return                      host
         */
        host_t *(*get_host) (endpoint_notify_t *this);
        
        /**
-        * @brief Returns the base of this endpoint.
+        * Returns the base of this endpoint.
         * 
         * If this is not a SERVER_REFLEXIVE endpoint, the returned host is the same
         * as the one returned by get_host.
         * 
-        * @param this          object
         * @return                      host
         */
        host_t *(*get_base) (endpoint_notify_t *this);
        
        /**
-        * @brief Generates a notification payload from this endpoint. 
+        * Generates a notification payload from this endpoint. 
         *      
-        * @param this          object
         * @return                      built notify_payload_t
         */
        notify_payload_t *(*build_notify) (endpoint_notify_t *this);
 
        /**
-        * @brief Clones an endpoint_notify_t object.
+        * Clones an endpoint_notify_t object.
         *
-        * @param this  endpoint_notify_t object to clone
-        * @return              cloned object
+        * @return                      cloned object
         */
        endpoint_notify_t *(*clone) (endpoint_notify_t *this);
        
        /**
-        * @brief Destroys an endpoint_notify_t object.
-        *
-        * @param this  endpoint_notify_t object to destroy
+        * Destroys an endpoint_notify_t object.
         */
        void (*destroy) (endpoint_notify_t *this);
 };
 
 /**
- * @brief Creates an empty endpoint_notify_t object.
+ * Creates an empty endpoint_notify_t object.
  * 
  * @return                     created endpoint_notify_t object
- * 
- * @ingroup payloads
  */
 endpoint_notify_t *endpoint_notify_create(void);
 
 
 /**
- * @brief Creates an endpoint_notify_t object from a host.
+ * Creates an endpoint_notify_t object from a host.
  * 
  * @param type         the endpoint type
  * @param host         host to base the notify on (gets cloned)
  * @param base         base of the endpoint, applies only to reflexive endpoints (gets cloned)
  * @return                     created endpoint_notify_t object
- * 
- * @ingroup payloads
  */
-endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, host_t *host, host_t *base);
+endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type,
+                                                                                                       host_t *host, host_t *base);
 
 /**
- * @brief Creates an endpoint_notify_t object from a notify payload.
+ * Creates an endpoint_notify_t object from a notify payload.
  * 
  * @param notify       the notify payload
  * @return                     - created endpoint_notify_t object
  *                                     - NULL if invalid payload
- * @ingroup payloads
  */
 endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify);
 
-#endif /*ENDPOINT_NOTIFY_H_*/
+#endif /*ENDPOINT_NOTIFY_H_ @} */
index aef8f6b7ec2db493b7675f0092a08de050246b74..f3168db81166dd75124f5e70b6ec4a3a5eb517c2 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file id_payload.h
- * 
- * @brief Interface of id_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
@@ -21,6 +14,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 8e9322b4adbba6ce439c2d95b6bb19adbc438fdd..a45b0a14c7d562fc53a12d94c924bc0b5a54291a 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file id_payload.h
- * 
- * @brief Interface of id_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * WITHOUT ANY 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 id_payload id_payload
+ * @{ @ingroup payloads
+ */
 
 #ifndef ID_PAYLOAD_H_
 #define ID_PAYLOAD_H_
@@ -34,8 +33,6 @@ typedef struct id_payload_t id_payload_t;
 
 /**
  * Length of a id payload without the data in bytes.
- * 
- * @ingroup payloads
  */
 #define ID_PAYLOAD_HEADER_LENGTH 8
 
@@ -43,12 +40,6 @@ typedef struct id_payload_t id_payload_t;
  * Object representing an IKEv2 ID payload.
  *
  * The ID payload format is described in RFC section 3.5.
- *
- * @b Constructors:
- * - id_payload_create_from_identification()
- * - id_payload_create()
- *
- * @ingroup payloads
  */
 struct id_payload_t {
        /**
@@ -57,90 +48,77 @@ struct id_payload_t {
        payload_t payload_interface;
 
        /**
-        * @brief Set the ID type.
+        * Set the ID type.
         *
-        * @param this                  calling id_payload_t object
         * @param type                  Type of ID
         */
        void (*set_id_type) (id_payload_t *this, id_type_t type);
        
        /**
-        * @brief Get the ID type.
+        * Get the ID type.
         *
-        * @param this                  calling id_payload_t object
         * @return                              type of the ID 
         */
        id_type_t (*get_id_type) (id_payload_t *this);
        
        /**
-        * @brief Set the ID data.
+        * Set the ID data.
         * 
         * Data are getting cloned.
         *
-        * @param this                  calling id_payload_t object
         * @param data                  ID data as chunk_t
         */
        void (*set_data) (id_payload_t *this, chunk_t data);
        
        /**
-        * @brief Get the ID data.
+        * Get the ID data.
         * 
         * Returned data are a copy of the internal one
         *
-        * @param this                  calling id_payload_t object
         * @return                              ID data as chunk_t
         */
        chunk_t (*get_data_clone) (id_payload_t *this);
        
        /**
-        * @brief Get the ID data.
+        * Get the ID data.
         * 
         * Returned data are NOT copied.
         *
-        * @param this                  calling id_payload_t object
         * @return                              ID data as chunk_t
         */
        chunk_t (*get_data) (id_payload_t *this);
 
        /**
-        * @brief Creates an identification object of this id payload.
+        * Creates an identification object of this id payload.
         * 
         * Returned object has to get destroyed by the caller.
         *
-        * @param this                  calling id_payload_t object
         * @return                              identification_t object 
         */
        identification_t *(*get_identification) (id_payload_t *this);
        
        /**
-        * @brief Destroys an id_payload_t object.
-        *
-        * @param this  id_payload_t object to destroy
+        * Destroys an id_payload_t object.
         */
        void (*destroy) (id_payload_t *this);
 };
 
 /**
- * @brief Creates an empty id_payload_t object.
+ * Creates an empty id_payload_t object.
  * 
  * @param payload_type one of ID_INITIATOR, ID_RESPONDER
  * @return                             id_payload_t object
- * 
- * @ingroup payloads
  */
 id_payload_t *id_payload_create(payload_type_t payload_type);
 
 /**
- * @brief Creates an id_payload_t from an existing identification_t object.
+ * Creates an id_payload_t from an existing identification_t object.
  * 
  * @param payload_type         one of ID_INITIATOR, ID_RESPONDER
  * @param identification       identification_t object
  * @return                                     id_payload_t object
- * 
- * @ingroup payloads
  */
-id_payload_t *id_payload_create_from_identification(payload_type_t payload_type, identification_t *identification);
-
-
+id_payload_t *id_payload_create_from_identification(payload_type_t payload_type,
+                                                                                       identification_t *identification);
 
-#endif /* ID_PAYLOAD_H_ */
+#endif /* ID_PAYLOAD_H_ @} */
index 3a171b095aaf36b822bda89e92b0bb20fd1a6baa..dbe0ee2a1033e22286de070477acda7279052598 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_header.c
- * 
- * @brief Implementation of ike_header_t. 
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
@@ -20,6 +13,8 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
+ *
+ * $Id$
  */
 
 /* offsetof macro */
index e80964482a04f323c1094a6bba93f0ab80a0d3c8..d66db937496caa7facaacd34da2fd633f0ff1ea6 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_header.h
- * 
- * @brief Interface of ike_header_t. 
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * WITHOUT ANY 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 ike_header ike_header
+ * @{ @ingroup payloads
  */
 
 #ifndef IKE_HEADER_H_
@@ -33,38 +33,28 @@ typedef struct ike_header_t ike_header_t;
 
 /**
  * Major Version of IKEv2.
- * 
- * @ingroup payloads
  */
 #define IKE_MAJOR_VERSION 2
 
 /**
  * Minor Version of IKEv2.
- * 
- * @ingroup payloads
  */
 #define IKE_MINOR_VERSION 0
 
 /**
  * Flag in IKEv2-Header. Always 0.
- * 
- * @ingroup payloads
  */
 #define HIGHER_VERSION_SUPPORTED_FLAG 0
 
 /**
  * Length of IKE Header in Bytes.
- * 
- * @ingroup payloads
  */
 #define IKE_HEADER_LENGTH 28
 
 /**
- * @brief Different types of IKE-Exchanges.
+ * Different types of IKE-Exchanges.
  *
- * See Draft for different types.
- * 
- * @ingroup payloads
+ * See RFC for different types.
  */
 enum exchange_type_t{
 
@@ -102,23 +92,16 @@ enum exchange_type_t{
 
 /**
  * enum name for exchange_type_t
- * 
- * @ingroup payloads
  */
 extern enum_name_t *exchange_type_names;
 
 /**
- * @brief An object of this type represents an IKEv2 header and is used to 
+ * An object of this type represents an IKEv2 header and is used to 
  * generate and parse IKEv2 headers.
  * 
  * The header format of an IKEv2-Message is compatible to the 
  * ISAKMP-Header format to allow implementations supporting 
  * both versions of the IKE-protocol.
- * 
- * @b Constructors:
- * - ike_header_create()
- * 
- * @ingroup payloads
  */
 struct ike_header_t {
        /**
@@ -127,141 +110,121 @@ struct ike_header_t {
        payload_t payload_interface;
        
        /**
-        * @brief Get the initiator spi.
+        * Get the initiator spi.
         *
-        * @param this                  ike_header_t object
         * @return                              initiator_spi
         */
        u_int64_t (*get_initiator_spi) (ike_header_t *this);
        
        /**
-        * @brief Set the initiator spi.
+        * Set the initiator spi.
         *
-        * @param this                  ike_header_t object
         * @param initiator_spi initiator_spi
         */
        void (*set_initiator_spi) (ike_header_t *this, u_int64_t initiator_spi);
        
        /**
-        * @brief Get the responder spi.
+        * Get the responder spi.
         *
-        * @param this                  ike_header_t object
         * @return                              responder_spi
         */
        u_int64_t (*get_responder_spi) (ike_header_t *this);
        
        /**
-        * @brief Set the responder spi.
+        * Set the responder spi.
         *
-        * @param this                  ike_header_t object
         * @param responder_spi responder_spi
         */
        void (*set_responder_spi) (ike_header_t *this, u_int64_t responder_spi);
        
        /**
-        * @brief Get the major version.
+        * Get the major version.
         *
-        * @param this                  ike_header_t object
         * @return                              major version
         */
        u_int8_t (*get_maj_version) (ike_header_t *this);
        
        /**
-        * @brief Get the minor version.
+        * Get the minor version.
         *
-        * @param this                  ike_header_t object
         * @return                              minor version
         */
        u_int8_t (*get_min_version) (ike_header_t *this);
        
        /**
-        * @brief Get the response flag.
+        * Get the response flag.
         *
-        * @param this                  ike_header_t object
         * @return                              response flag
         */
        bool (*get_response_flag) (ike_header_t *this);
        
        /**
-        * @brief Set the response flag-
+        * Set the response flag-
         *
-        * @param this                  ike_header_t object
         * @param response              response flag
         * 
         */
        void (*set_response_flag) (ike_header_t *this, bool response);
        /**
-        * @brief Get "higher version supported"-flag.
+        * Get "higher version supported"-flag.
         *
-        * @param this                  ike_header_t object
         * @return                              version flag
         */
        bool (*get_version_flag) (ike_header_t *this);
        
        /**
-        * @brief Get the initiator flag.
+        * Get the initiator flag.
         *
-        * @param this                  ike_header_t object
         * @return                              initiator flag
         */
        bool (*get_initiator_flag) (ike_header_t *this);
        
        /**
-        * @brief Set the initiator flag.
+        * Set the initiator flag.
         *
-        * @param this                  ike_header_t object
         * @param initiator             initiator flag
-        * 
         */
        void (*set_initiator_flag) (ike_header_t *this, bool initiator);
 
        /**
-        * @brief Get the exchange type.
+        * Get the exchange type.
         *
-        * @param this                  ike_header_t object
-        * @return                               exchange type
+        * @return                              exchange type
         */
        u_int8_t (*get_exchange_type) (ike_header_t *this);
        
        /**
-        * @brief Set the  exchange type.
+        * Set the  exchange type.
         *
-        * @param this                  ike_header_t object
         * @param exchange_type exchange type
         */
        void (*set_exchange_type) (ike_header_t *this, u_int8_t exchange_type);
        
        /**
-        * @brief Get the message id.
+        * Get the message id.
         *
-        * @param this                  ike_header_t object
         * @return                              message id
         */
        u_int32_t (*get_message_id) (ike_header_t *this);
        
        /**
-        * @brief Set the message id.
+        * Set the message id.
         *
-        * @param this                  ike_header_t object
         * @param initiator_spi message id
         */
        void (*set_message_id) (ike_header_t *this, u_int32_t message_id);
        
        /**
-        * @brief Destroys a ike_header_t object.
-        *
-        * @param this                  ike_header_t object to destroy
+        * Destroys a ike_header_t object.
         */
        void (*destroy) (ike_header_t *this);
 };
 
 /**
- * @brief Create an ike_header_t object
+ * Create an ike_header_t object
  * 
  * @return ike_header_t object
- * 
- * @ingroup payloads
  */
 ike_header_t *ike_header_create(void);
 
-#endif /*IKE_HEADER_H_*/
+#endif /*IKE_HEADER_H_ @} */
index 8926b15f9a0d455de3e71667bf00bcf393ce8d23..200ec4d941646652567e79799426cda8e7253ce4 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ke_payload.c
- * 
- * @brief Implementation of ke_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 52be8ffe3b3e53059e1aaa593164310ed752aba3..7cd2448ba138c14c366f49f5256b7837015bcf6e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ke_payload.h
- * 
- * @brief Interface of ke_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 ke_payload ke_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef KE_PAYLOAD_H_
@@ -34,20 +34,13 @@ typedef struct ke_payload_t ke_payload_t;
 
 /**
  * KE payload length in bytes without any key exchange data.
- * 
- * @ingroup payloads
  */
 #define KE_PAYLOAD_HEADER_LENGTH 8
 
 /**
- * @brief Class representing an IKEv2-KE Payload.
+ * Class representing an IKEv2-KE Payload.
  *
  * The KE Payload format is described in RFC section 3.4.
- *
- * @b Constructors:
- * - ke_payload_create()
- *
- * @ingroup payloads
  */
 struct ke_payload_t {
        /**
@@ -56,66 +49,58 @@ struct ke_payload_t {
        payload_t payload_interface;
        
        /**
-        * @brief Returns the currently set key exchange data of this KE payload.
+        * Returns the currently set key exchange data of this KE payload.
         *      
         * @warning Returned data are not copied.
         * 
-        * @param this  calling ke_payload_t object
         * @return              chunk_t pointing to the value
         */
        chunk_t (*get_key_exchange_data) (ke_payload_t *this);
        
        /**
-        * @brief Sets the key exchange data of this KE payload.
+        * Sets the key exchange data of this KE payload.
         *      
-        * @warning Value is getting copied.
+        * Value is getting copied.
         * 
-        * @param this                          calling ke_payload_t object
-        * @param key_exchange_data     chunk_t pointing to the value to set
+        * @param key_exchange_data chunk_t pointing to the value to set
         */
        void (*set_key_exchange_data) (ke_payload_t *this, chunk_t key_exchange_data);
 
        /**
-        * @brief Gets the Diffie-Hellman Group Number of this KE payload.
+        * Gets the Diffie-Hellman Group Number of this KE payload.
         *      
-        * @param this          calling ke_payload_t object
-        * @return                      DH Group Number of this payload
+        * @return                                      DH Group Number of this payload
         */
        diffie_hellman_group_t (*get_dh_group_number) (ke_payload_t *this);
 
        /**
-        * @brief Sets the Diffie-Hellman Group Number of this KE payload.
+        * Sets the Diffie-Hellman Group Number of this KE payload.
         *      
-        * @param this                          calling ke_payload_t object
         * @param dh_group_number       DH Group to set
         */
-       void (*set_dh_group_number) (ke_payload_t *this, diffie_hellman_group_t dh_group_number);
+       void (*set_dh_group_number) (ke_payload_t *this, 
+                                                                diffie_hellman_group_t dh_group_number);
 
        /**
-        * @brief Destroys an ke_payload_t object.
-        *
-        * @param this  ke_payload_t object to destroy
+        * Destroys an ke_payload_t object.
         */
        void (*destroy) (ke_payload_t *this);
 };
 
 /**
- * @brief Creates an empty ke_payload_t object
+ * Creates an empty ke_payload_t object
  * 
  * @return ke_payload_t object
- * 
- * @ingroup payloads
  */
 ke_payload_t *ke_payload_create(void);
 
 /**
- * @brief Creates a ke_payload_t from a diffie_hellman_t
+ * Creates a ke_payload_t from a diffie_hellman_t
  * 
  * @param diffie_hellman       diffie hellman object containing group and key
  * @return                                     ke_payload_t object
- * 
- * @ingroup payloads
  */
-ke_payload_t *ke_payload_create_from_diffie_hellman(diffie_hellman_t *diffie_hellman);
+ke_payload_t *ke_payload_create_from_diffie_hellman(
+                                                                                       diffie_hellman_t *diffie_hellman);
 
-#endif /* KE_PAYLOAD_H_ */
+#endif /* KE_PAYLOAD_H_ @} */
index 8e1fc505e2329e84ba9462ac661a239a4703ab2d..4afe3807e9dcea8629aaa561ec12a80e0a8ef7d6 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file nonce_payload.h
- * 
- * @brief Implementation of nonce_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
+ *
+ * $Id$
  */
  
 /* offsetof macro */
index 96d83b0280f9eb631e662361792f2b9e9121985d..b0a63a28afb551acb71797058f13f5b3e9800af9 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file nonce_payload.h
- * 
- * @brief Interface of nonce_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 nonce_payload nonce_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef NONCE_PAYLOAD_H_
@@ -31,17 +31,11 @@ typedef struct nonce_payload_t nonce_payload_t;
 
 /**
  * Nonce size in bytes for nonces sending to other peer.
- * 
- * @warning Nonce size MUST be between 16 and 256 bytes.
- * 
- * @ingroup payloads
  */
 #define NONCE_SIZE 16
 
 /**
  * Length of a nonce payload without a nonce in bytes.
- * 
- * @ingroup payloads
  */
 #define NONCE_PAYLOAD_HEADER_LENGTH 4
 
@@ -49,11 +43,6 @@ typedef struct nonce_payload_t nonce_payload_t;
  * Object representing an IKEv2 Nonce payload.
  * 
  * The Nonce payload format is described in RFC section 3.3.
- * 
- * @b Constructors:
- * - nonce_payload_create()
- * 
- * @ingroup payloads
  */
 struct nonce_payload_t {
        /**
@@ -62,38 +51,30 @@ struct nonce_payload_t {
        payload_t payload_interface;
 
        /**
-        * @brief Set the nonce value.
+        * Set the nonce value.
         *
-        * @param this                  calling nonce_payload_t object
         * @param nonce                 chunk containing the nonce, will be cloned
         */
        void (*set_nonce) (nonce_payload_t *this, chunk_t nonce);
        
        /**
-        * @brief Get the nonce value.
+        * Get the nonce value.
         *
-        * @param this                  calling nonce_payload_t object
         * @return                              a chunk containing the cloned nonce
         */
        chunk_t (*get_nonce) (nonce_payload_t *this);
        
        /**
-        * @brief Destroys an nonce_payload_t object.
-        *
-        * @param this  nonce_payload_t object to destroy
+        * Destroys an nonce_payload_t object.
         */
        void (*destroy) (nonce_payload_t *this);
 };
 
 /**
- * @brief Creates an empty nonce_payload_t object
+ * Creates an empty nonce_payload_t object
  * 
  * @return nonce_payload_t object
- * 
- * @ingroup payloads
  */
 nonce_payload_t *nonce_payload_create(void);
 
-
-#endif /*NONCE_PAYLOAD_H_*/
+#endif /*NONCE_PAYLOAD_H_ @} */
index d32257af60bb22c758523db330bff098e7e607a8..0950f6b8aa98a3f9ee1e572a143576a73e23120a 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file notify_payload.c
- * 
- * @brief Implementation of notify_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
@@ -21,6 +14,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 03f61d4732d8b5fea6d572913126869544b19fe1..2f147c929eb507af6bc68c3460ad4f8c78c43cd8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file notify_payload.h
- * 
- * @brief Interface of notify_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * WITHOUT ANY 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 notify_payload notify_payload
+ * @{ @ingroup payloads
+ */
 
 #ifndef NOTIFY_PAYLOAD_H_
 #define NOTIFY_PAYLOAD_H_
@@ -37,17 +36,13 @@ typedef struct notify_payload_t notify_payload_t;
 
 /**
  * Notify payload length in bytes without any spi and notification data.
- * 
- * @ingroup payloads
  */
 #define NOTIFY_PAYLOAD_HEADER_LENGTH 8
 
 /**
- * @brief Notify message types.
+ * Notify message types.
  *
  * See IKEv2 RFC 3.10.1.
- *
- * @ingroup payloads
  */
 enum notify_type_t {
        /* notify error messages */
@@ -109,30 +104,18 @@ enum notify_type_t {
 
 /**
  * enum name for notify_type_t.
- *
- * @ingroup payloads
  */
 extern enum_name_t *notify_type_names;
 
 /**
  * enum name for notify_type_t (shorter strings).
- *
- * @ingroup payloads
  */
 extern enum_name_t *notify_type_short_names;
 
 /**
- * @brief Class representing an IKEv2-Notify Payload.
+ * Class representing an IKEv2-Notify Payload.
  * 
  * The Notify Payload format is described in Draft section 3.10.
- * 
- * @b Constructors:
- * - notify_payload_create()
- * - notify_payload_create_from_protocol_and_type()
- * 
- * @todo Build specified constructor/getter for notify's
- *
- * @ingroup payloads
  */
 struct notify_payload_t {
        /**
@@ -141,104 +124,91 @@ struct notify_payload_t {
        payload_t payload_interface;
        
        /**
-        * @brief Gets the protocol id of this payload.
+        * Gets the protocol id of this payload.
         *      
-        * @param this          calling notify_payload_t object
         * @return                      protocol id of this payload
         */
        u_int8_t (*get_protocol_id) (notify_payload_t *this);
 
        /**
-        * @brief Sets the protocol id of this payload.
+        * Sets the protocol id of this payload.
         *      
-        * @param this                  calling notify_payload_t object
         * @param protocol_id   protocol id to set
         */
        void (*set_protocol_id) (notify_payload_t *this, u_int8_t protocol_id);
 
        /**
-        * @brief Gets the notify message type of this payload.
+        * Gets the notify message type of this payload.
         *      
-        * @param this          calling notify_payload_t object
         * @return                      notify message type of this payload
         */
        notify_type_t (*get_notify_type) (notify_payload_t *this);
 
        /**
-        * @brief Sets notify message type of this payload.
+        * Sets notify message type of this payload.
         *      
-        * @param this          calling notify_payload_t object
         * @param type          notify message type to set
         */
        void (*set_notify_type) (notify_payload_t *this, notify_type_t type);
 
        /**
-        * @brief Returns the currently set spi of this payload.
+        * Returns the currently set spi of this payload.
         * 
         * This is only valid for notifys with protocol AH|ESP
         *
-        * @param this  calling notify_payload_t object
         * @return              SPI value
         */
        u_int32_t (*get_spi) (notify_payload_t *this);
        
        /**
-        * @brief Sets the spi of this payload.
+        * Sets the spi of this payload.
         * 
         * This is only valid for notifys with protocol AH|ESP
         * 
-        * @param this  calling notify_payload_t object
         * @param spi   SPI value
         */
        void (*set_spi) (notify_payload_t *this, u_int32_t spi);
 
        /**
-        * @brief Returns the currently set notification data of payload.
+        * Returns the currently set notification data of payload.
         *      
-        * @warning Returned data are not copied.
+        * Returned data are not copied.
         * 
-        * @param this  calling notify_payload_t object
         * @return              chunk_t pointing to the value
         */
        chunk_t (*get_notification_data) (notify_payload_t *this);
        
        /**
-        * @brief Sets the notification data of this payload.
+        * Sets the notification data of this payload.
         *      
         * @warning Value is getting copied.
         * 
-        * @param this                                  calling notify_payload_t object
         * @param notification_data     chunk_t pointing to the value to set
         */
-       void (*set_notification_data) (notify_payload_t *this, chunk_t notification_data);
+       void (*set_notification_data) (notify_payload_t *this,
+                                                                  chunk_t notification_data);
 
        /**
-        * @brief Destroys an notify_payload_t object.
-        *
-        * @param this  notify_payload_t object to destroy
+        * Destroys an notify_payload_t object.
         */
        void (*destroy) (notify_payload_t *this);
 };
 
 /**
- * @brief Creates an empty notify_payload_t object
+ * Creates an empty notify_payload_t object
  * 
  * @return                     created notify_payload_t object
- * 
- * @ingroup payloads
  */
 notify_payload_t *notify_payload_create(void);
 
 /**
- * @brief Creates an notify_payload_t object of specific type for specific protocol id.
+ * Creates an notify_payload_t object of specific type for specific protocol id.
  * 
  * @param protocol_id                  protocol id (IKE, AH or ESP)
  * @param type                                 notify type (see notify_type_t)
  * @return                                             notify_payload_t object
- * 
- * @ingroup payloads
  */
-notify_payload_t *notify_payload_create_from_protocol_and_type(protocol_id_t protocol_id, notify_type_t type);
-
+notify_payload_t *notify_payload_create_from_protocol_and_type(
+                                                               protocol_id_t protocol_id, notify_type_t type);
 
-#endif /*NOTIFY_PAYLOAD_H_*/
+#endif /*NOTIFY_PAYLOAD_H_ @} */
index 2c51c60dee8248a4a3350d5521a90d8c5b21b93d..6e6a6e281504fc078f88f5dc4849847a45543afb 100644 (file)
@@ -1,11 +1,3 @@
-/**
- * @file payload.c
- * 
- * @brief Generic constructor to the payload_t interface.
- * 
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
@@ -21,6 +13,8 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
+ *
+ * $Id$
  */
 
 
index ab902d755734a260d48896bd3efec0713d6b6628..a2c6e296d612f54a8cdf0fe45aaca4a70b3a17c0 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file payload.h
- * 
- * @brief Interface payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * WITHOUT ANY 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 payload payload
+ * @{ @ingroup payloads
  */
 
 #ifndef PAYLOAD_H_
@@ -33,12 +33,10 @@ typedef struct payload_t payload_t;
 
 
 /**
- * @brief Payload-Types of a IKEv2-Message.
+ * Payload-Types of a IKEv2-Message.
  *
  * Header and substructures are also defined as 
  * payload types with values from PRIVATE USE space.
- *
- * @ingroup payloads
  */
 enum payload_type_t{
 
@@ -204,80 +202,65 @@ extern enum_name_t *payload_type_names;
 extern enum_name_t *payload_type_short_names;
 
 /**
- * @brief Generic interface for all payload types (incl.header and substructures).
+ * Generic interface for all payload types (incl.header and substructures).
  * 
  * To handle all kinds of payloads on a generic way, this interface must
  * be implemented by every payload. This allows parser_t/generator_t a simple
  * handling of all payloads.
- * 
- * @b Constructors:
- * - payload_create() with the payload to instantiate.
- * 
- * @ingroup payloads
  */
 struct payload_t {
        
        /**
-        * @brief Get encoding rules for this payload.
+        * Get encoding rules for this payload.
         *
-        * @param this                          calling object
-        * @param[out] rules            location to store pointer of first rule
-        * @param[out] rule_count       location to store number of rules
+        * @param rules                 location to store pointer of first rule
+        * @param rule_count    location to store number of rules
         */
        void (*get_encoding_rules) (payload_t *this, encoding_rule_t **rules, size_t *rule_count);
 
        /**
-        * @brief Get type of payload.
+        * Get type of payload.
         *
-        * @param this                          calling object
-        * @return                                      type of this payload
+        * @return                              type of this payload
         */
        payload_type_t (*get_type) (payload_t *this);
 
        /**
-        * @brief Get type of next payload or NO_PAYLOAD (0) if this is the last one.
+        * Get type of next payload or NO_PAYLOAD (0) if this is the last one.
         *
-        * @param this                          calling object
-        * @return                                      type of next payload
+        * @return                              type of next payload
         */
        payload_type_t (*get_next_type) (payload_t *this);
        
        /**
-        * @brief Set type of next payload.
+        * Set type of next payload.
         *
-        * @param this                          calling object
-        * @param type                          type of next payload
+        * @param type                  type of next payload
         */
        void (*set_next_type) (payload_t *this,payload_type_t type);
 
        /**
-        * @brief Get length of payload.
+        * Get length of payload.
         *
-        * @param this                          calling object
-        * @return                                      length of this payload
+        * @return                              length of this payload
         */
        size_t (*get_length) (payload_t *this);
        
        /**
-        * @brief Verifies payload structure and makes consistence check.
+        * Verifies payload structure and makes consistence check.
         *
-        * @param this                          calling object
-        * @return                                      
-        *                                                      - SUCCESS
-        *                                                      - FAILED if consistence not given
+        * @return                              SUCCESS,  FAILED if consistence not given
         */
        status_t (*verify) (payload_t *this);
        
        /**
-        * @brief Destroys a payload and all included substructures.
-        *
-        * @param this                          payload to destroy
+        * Destroys a payload and all included substructures.
         */
        void (*destroy) (payload_t *this);
 };
 
 /**
- * @brief Create an empty payload.
+ * Create an empty payload.
  * 
  * Useful for the parser, who wants a generic constructor for all payloads.
  * It supports all payload_t methods. If a payload type is not known, 
@@ -288,4 +271,4 @@ struct payload_t {
  */
 payload_t *payload_create(payload_type_t type);
 
-#endif /*PAYLOAD_H_*/
+#endif /*PAYLOAD_H_ @} */
index 182d2b6e86094bf6c0e813912bbfc242d1bbe5a2..0baa5c286b149a12e3d882a6ce1a5962d28e5860 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file proposal_substructure.h
- * 
- * @brief Implementation of proposal_substructure_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 93a8d7b2fdf963843cb263d4c3904ba3c116f58b..c3a57ab22eccd70c996eb1d054582c0217917736 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file proposal_substructure.h
- * 
- * @brief Interface of proposal_substructure_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 proposal_substructure proposal_substructure
+ * @{ @ingroup payloads
  */
 
 #ifndef PROPOSAL_SUBSTRUCTURE_H_
@@ -35,20 +35,13 @@ typedef struct proposal_substructure_t proposal_substructure_t;
 
 /**
  * Length of the proposal substructure header (without spi).
- * 
- * @ingroup payloads
  */
 #define PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH 8
 
 /**
- * @brief Class representing an IKEv2-PROPOSAL SUBSTRUCTURE.
+ * Class representing an IKEv2-PROPOSAL SUBSTRUCTURE.
  * 
  * The PROPOSAL SUBSTRUCTURE format is described in RFC section 3.3.1.
- * 
- * @b Constructors:
- * - proposal_substructure_create()
- * 
- * @ingroup payloads
  */
 struct proposal_substructure_t {
        /**
@@ -57,150 +50,126 @@ struct proposal_substructure_t {
        payload_t payload_interface;
 
        /**
-        * @brief Creates an iterator of stored transform_substructure_t objects.
-        * 
-        * @warning The created iterator has to get destroyed by the caller!
-        *                      When deleting any transform over this iterator, call 
-        *                      get_size to make sure the length and number values are ok.
+        * Creates an iterator of stored transform_substructure_t objects.
         *
-        * @param this                  calling proposal_substructure_t object
         * @param forward               iterator direction (TRUE: front to end)
         * @return                              created iterator_t object
         */
-       iterator_t *(*create_transform_substructure_iterator) (proposal_substructure_t *this, bool forward);
+       iterator_t *(*create_transform_substructure_iterator) (
+                                                               proposal_substructure_t *this, bool forward);
        
        /**
-        * @brief Adds a transform_substructure_t object to this object.
-        * 
-        * @warning The added transform_substructure_t object is
-        *                      getting destroyed in destroy function of proposal_substructure_t.
+        * Adds a transform_substructure_t object to this object.
         *
-        * @param this          calling proposal_substructure_t object
-        * @param transform transform_substructure_t object to add
+        * @param transform     transform_substructure_t object to add
         */
-       void (*add_transform_substructure) (proposal_substructure_t *this,transform_substructure_t *transform);
+       void (*add_transform_substructure) (proposal_substructure_t *this,
+                                                                               transform_substructure_t *transform);
        
        /**
-        * @brief Sets the proposal number of current proposal.
+        * Sets the proposal number of current proposal.
         *
-        * @param this          calling proposal_substructure_t object
-        * @param id            proposal number to set
+        * @param id                    proposal number to set
         */
-       void (*set_proposal_number) (proposal_substructure_t *this,u_int8_t proposal_number);
+       void (*set_proposal_number) (proposal_substructure_t *this,
+                                                                u_int8_t proposal_number);
        
        /**
-        * @brief get proposal number of current proposal.
+        * get proposal number of current proposal.
         * 
-        * @param this          calling proposal_substructure_t object
         * @return                      proposal number of current proposal substructure.
         */
        u_int8_t (*get_proposal_number) (proposal_substructure_t *this);
 
        /**
-        * @brief get the number of transforms in current proposal.
+        * get the number of transforms in current proposal.
         * 
-        * @param this          calling proposal_substructure_t object
         * @return                      transform count in current proposal
         */
        size_t (*get_transform_count) (proposal_substructure_t *this);
 
        /**
-        * @brief get size of the set spi in bytes.
+        * get size of the set spi in bytes.
         * 
-        * @param this          calling proposal_substructure_t object
         * @return                      size of the spi in bytes
         */
        size_t (*get_spi_size) (proposal_substructure_t *this);
 
        /**
-        * @brief Sets the protocol id of current proposal.
+        * Sets the protocol id of current proposal.
         *
-        * @param this          calling proposal_substructure_t object
-        * @param id                    protocol id to set
+        * @param id            protocol id to set
         */
-       void (*set_protocol_id) (proposal_substructure_t *this,u_int8_t protocol_id);
+       void (*set_protocol_id) (proposal_substructure_t *this,
+                                                        u_int8_t protocol_id);
        
        /**
-        * @brief get protocol id of current proposal.
+        * get protocol id of current proposal.
         * 
-        * @param this          calling proposal_substructure_t object
         * @return                      protocol id of current proposal substructure.
         */
        u_int8_t (*get_protocol_id) (proposal_substructure_t *this);
        
        /**
-        * @brief Sets the next_payload field of this substructure
+        * Sets the next_payload field of this substructure
         * 
         * If this is the last proposal, next payload field is set to 0,
         * otherwise to 2
         *
-        * @param this          calling proposal_substructure_t object
         * @param is_last       When TRUE, next payload field is set to 0, otherwise to 2
         */
        void (*set_is_last_proposal) (proposal_substructure_t *this, bool is_last);
        
        /**
-        * @brief Returns the currently set SPI of this proposal.
-        *      
-        * @warning Returned data are not copied
-        * 
-        * @param this  calling proposal_substructure_t object
-        * @return              chunk_t pointing to the value
+        * Returns the currently set SPI of this proposal.
+        *
+        * @return                      chunk_t pointing to the value
         */
        chunk_t (*get_spi) (proposal_substructure_t *this);
        
        /**
-        * @brief Sets the SPI of the current proposal.
+        * Sets the SPI of the current proposal.
         *      
         * @warning SPI is getting copied
         * 
-        * @param this  calling proposal_substructure_t object
-        * @param spi   chunk_t pointing to the value to set
+        * @param spi           chunk_t pointing to the value to set
         */
        void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
        
        /**
-        * @brief Get a proposal_t from the propsal_substructure_t.
+        * Get a proposal_t from the propsal_substructure_t.
         * 
-        * @param this          calling proposal_substructure_t object
         * @return                      proposal_t
         */
        proposal_t * (*get_proposal) (proposal_substructure_t *this);
 
        /**
-        * @brief Clones an proposal_substructure_t object.
+        * Clones an proposal_substructure_t object.
         *
-        * @param this  proposal_substructure_t object to clone
         * @return              cloned object
         */
        proposal_substructure_t* (*clone) (proposal_substructure_t *this);
 
        /**
-        * @brief Destroys an proposal_substructure_t object.
-        *
-        * @param this  proposal_substructure_t object to destroy
+        * Destroys an proposal_substructure_t object.
         */
        void (*destroy) (proposal_substructure_t *this);
 };
 
 /**
- * @brief Creates an empty proposal_substructure_t object
+ * Creates an empty proposal_substructure_t object
  * 
  * @return proposal_substructure_t object
- * 
- * @ingroup payloads
  */
 proposal_substructure_t *proposal_substructure_create(void);
 
 /**
- * @brief Creates a proposal_substructure_t from a proposal_t.
+ * Creates a proposal_substructure_t from a proposal_t.
  *
  * @param proposal             proposal to build a substruct out of it
  * @return                             proposal_substructure_t object
- * 
- * @ingroup payloads
  */
-proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal);
-
+proposal_substructure_t *proposal_substructure_create_from_proposal(
+                                                                                                               proposal_t *proposal);
 
-#endif /*PROPOSAL_SUBSTRUCTURE_H_*/
+#endif /*PROPOSAL_SUBSTRUCTURE_H_ @} */
index 304f1b64c7784b0afcf62cbafbd97336824d0c85..950e16d253d2d272d3f1564bb284fbf225eb6c2a 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file sa_payload.c
- * 
- * @brief Implementation of sa_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 67d6878575ca667d4027be90f56e6d94d600c200..97beecf4e8382ad0d6e836df81a8da4fd18a0f5a 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file sa_payload.h
- * 
- * @brief Interface of sa_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 sa_payload sa_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef SA_PAYLOAD_H_
@@ -33,24 +33,13 @@ typedef struct sa_payload_t sa_payload_t;
 
 /**
  * SA_PAYLOAD length in bytes without any proposal substructure.
- * 
- * @ingroup payloads
  */
 #define SA_PAYLOAD_HEADER_LENGTH 4
 
 /**
- * @brief Class representing an IKEv2-SA Payload.
+ * Class representing an IKEv2-SA Payload.
  *
  * The SA Payload format is described in RFC section 3.3.
- *
- * @b Constructors:
- * - sa_payload_create()
- * - sa_payload_create_from_ike_proposals()
- * - sa_payload_create_from_proposal()
- *
- * @todo Add support of algorithms without specified keylength in get_proposals and get_ike_proposals.
- *
- * @ingroup payloads
  */
 struct sa_payload_t {
        /**
@@ -59,83 +48,70 @@ struct sa_payload_t {
        payload_t payload_interface;
        
        /**
-        * @brief Creates an iterator of stored proposal_substructure_t objects.
+        * Creates an iterator of stored proposal_substructure_t objects.
         * 
-        * @warning The created iterator has to get destroyed by the caller!
-        * 
-        * @warning When deleting an proposal using this iterator, 
-        *                      the length of this transform substructure has to be refreshed 
-        *                      by calling get_length()!
+        * When deleting an proposal using this iterator, 
+        * the length of this transform substructure has to be refreshed 
+        * by calling get_length()!
         *
-        * @param this                          calling sa_payload_t object
-        * @param[in] forward           iterator direction (TRUE: front to end)
-        * @return                                      created iterator_t object
+        * @param forward               iterator direction (TRUE: front to end)
+        * @return                              created iterator_t object
         */
-       iterator_t *(*create_proposal_substructure_iterator) (sa_payload_t *this, bool forward);
+       iterator_t *(*create_proposal_substructure_iterator) (sa_payload_t *this,
+                                                                                                                 bool forward);
        
        /**
-        * @brief Adds a proposal_substructure_t object to this object.
-        * 
-        * @warning The added proposal_substructure_t object  is 
-        *                      getting destroyed in destroy function of sa_payload_t.
+        * Adds a proposal_substructure_t object to this object.
         *
-        * @param this                          calling sa_payload_t object
         * @param proposal              proposal_substructure_t object to add
         */
-       void (*add_proposal_substructure) (sa_payload_t *this,proposal_substructure_t *proposal);
+       void (*add_proposal_substructure) (sa_payload_t *this,
+                                                                          proposal_substructure_t *proposal);
 
        /**
-        * @brief Gets the proposals in this payload as a list.
+        * Gets the proposals in this payload as a list.
         * 
         * @return                                      a list containing proposal_t s
         */
        linked_list_t *(*get_proposals) (sa_payload_t *this);
        
        /**
-        * @brief Add a child proposal (AH/ESP) to the payload.
+        * Add a child proposal (AH/ESP) to the payload.
         * 
         * @param proposal                      child proposal to add to the payload
         */
        void (*add_proposal) (sa_payload_t *this, proposal_t *proposal);
        
        /**
-        * @brief Destroys an sa_payload_t object.
-        *
-        * @param this  sa_payload_t object to destroy
+        * Destroys an sa_payload_t object.
         */
        void (*destroy) (sa_payload_t *this);
 };
 
 /**
- * @brief Creates an empty sa_payload_t object
+ * Creates an empty sa_payload_t object
  * 
  * @return                                     created sa_payload_t object
- * 
- * @ingroup payloads
  */
 sa_payload_t *sa_payload_create(void);
 
 /**
- * @brief Creates a sa_payload_t object from a list of proposals.
+ * Creates a sa_payload_t object from a list of proposals.
  * 
  * @param proposals                    list of proposals to build the payload from
  * @return                                     sa_payload_t object
- * 
- * @ingroup payloads
  */
 sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
 
 /**
- * @brief Creates a sa_payload_t object from a single proposal.
+ * Creates a sa_payload_t object from a single proposal.
  * 
  * This is only for convenience. Use sa_payload_create_from_proposal_list
  * if you want to add more than one proposal.
  * 
  * @param proposal                     proposal from which the payload should be built.
  * @return                                     sa_payload_t object
- * 
- * @ingroup payloads
  */
 sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal);
 
-#endif /*SA_PAYLOAD_H_*/
+#endif /*SA_PAYLOAD_H_ @} */
index 573139bf3ba8cc4ddf4565af621f857ff24e3190..58ca408d5ff0fe27adc02bf2bc35ac7e225c10ba 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file traffic_selector_substructure.c
- * 
- * @brief Interface of traffic_selector_substructure_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "traffic_selector_substructure.h"
index 14efccc8989c910b89f350ff5be113983624d62f..1355b6599af3cd0e36f9e2e3f07cbff391219950 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file traffic_selector_substructure.h
- * 
- * @brief Interface of traffic_selector_substructure_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 traffic_selector_substructure traffic_selector_substructure
+ * @{ @ingroup payloads
+ */
 
 #ifndef TRAFFIC_SELECTOR_SUBSTRUCTURE_H_
 #define TRAFFIC_SELECTOR_SUBSTRUCTURE_H_
@@ -34,21 +33,13 @@ typedef struct traffic_selector_substructure_t traffic_selector_substructure_t;
 
 /**
  * Length of a TRAFFIC SELECTOR SUBSTRUCTURE without start and end address.
- * 
- * @ingroup payloads
  */
 #define TRAFFIC_SELECTOR_HEADER_LENGTH 8
 
 /**
- * @brief Class representing an IKEv2 TRAFFIC SELECTOR.
+ * Class representing an IKEv2 TRAFFIC SELECTOR.
  * 
  * The TRAFFIC SELECTOR format is described in RFC section 3.13.1.
- * 
- * @b Constructors:
- * - traffic_selector_substructure_create()
- * - traffic_selector_substructure_create_from_traffic_selector()
- * 
- * @ingroup payloads
  */
 struct traffic_selector_substructure_t {
        /**
@@ -57,116 +48,106 @@ struct traffic_selector_substructure_t {
        payload_t payload_interface;
        
        /**
-        * @brief Get the type of Traffic selector.
+        * Get the type of Traffic selector.
         *
-        * @param this          calling traffic_selector_substructure_t object
         * @return                      type of traffic selector
         *  
         */
        ts_type_t (*get_ts_type) (traffic_selector_substructure_t *this);
        
        /**
-        * @brief Set the type of Traffic selector.
+        * Set the type of Traffic selector.
         *
-        * @param this          calling traffic_selector_substructure_t object
         * @param ts_type       type of traffic selector        
         */
-       void (*set_ts_type) (traffic_selector_substructure_t *this,ts_type_t ts_type);
+       void (*set_ts_type) (traffic_selector_substructure_t *this,
+                                                ts_type_t ts_type);
        
        /**
-        * @brief Get the IP protocol ID of Traffic selector.
+        * Get the IP protocol ID of Traffic selector.
         *
-        * @param this          calling traffic_selector_substructure_t object
         * @return                      type of traffic selector
         *  
         */
        u_int8_t (*get_protocol_id) (traffic_selector_substructure_t *this);
        
        /**
-        * @brief Set the IP protocol ID of Traffic selector
+        * Set the IP protocol ID of Traffic selector
         *
-        * @param this                  calling traffic_selector_substructure_t object
         * @param protocol_id   protocol ID of traffic selector 
         */
-       void (*set_protocol_id) (traffic_selector_substructure_t *this,u_int8_t protocol_id);
+       void (*set_protocol_id) (traffic_selector_substructure_t *this,
+                                                         u_int8_t protocol_id);
        
        /**
-        * @brief Get the start port and address as host_t object.
+        * Get the start port and address as host_t object.
         *
         * Returned host_t object has to get destroyed by the caller.
         * 
-        * @param this          calling traffic_selector_substructure_t object
         * @return                      start host as host_t object
         *  
         */
        host_t *(*get_start_host) (traffic_selector_substructure_t *this);
        
        /**
-        * @brief Set the start port and address as host_t object.
+        * Set the start port and address as host_t object.
         *
-        * @param this                  calling traffic_selector_substructure_t object
         * @param start_host    start host as host_t object
         */
-       void (*set_start_host) (traffic_selector_substructure_t *this,host_t *start_host);
+       void (*set_start_host) (traffic_selector_substructure_t *this,
+                                                       host_t *start_host);
        
        /**
-        * @brief Get the end port and address as host_t object.
+        * Get the end port and address as host_t object.
         *
         * Returned host_t object has to get destroyed by the caller.
         * 
-        * @param this          calling traffic_selector_substructure_t object
         * @return                      end host as host_t object
         *  
         */
        host_t *(*get_end_host) (traffic_selector_substructure_t *this);
        
        /**
-        * @brief Set the end port and address as host_t object.
+        * Set the end port and address as host_t object.
         *
-        * @param this          calling traffic_selector_substructure_t object
         * @param end_host      end host as host_t object
         */
-       void (*set_end_host) (traffic_selector_substructure_t *this,host_t *end_host);
+       void (*set_end_host) (traffic_selector_substructure_t *this,
+                                                 host_t *end_host);
        
        /**
-        * @brief Get a traffic_selector_t from this substructure.
+        * Get a traffic_selector_t from this substructure.
         *
         * @warning traffic_selector_t must be destroyed after usage.
         * 
-        * @param this          calling traffic_selector_substructure_t object
         * @return                      contained traffic_selector_t
         */
-       traffic_selector_t *(*get_traffic_selector) (traffic_selector_substructure_t *this);
+       traffic_selector_t *(*get_traffic_selector) (
+                                                                               traffic_selector_substructure_t *this);
        
        /**
-        * @brief Destroys an traffic_selector_substructure_t object.
-        *
-        * @param this  traffic_selector_substructure_t object to destroy
+        * Destroys an traffic_selector_substructure_t object.
         */
        void (*destroy) (traffic_selector_substructure_t *this);
 };
 
 /**
- * @brief Creates an empty traffic_selector_substructure_t object.
+ * Creates an empty traffic_selector_substructure_t object.
  *
  * TS type is set to default TS_IPV4_ADDR_RANGE!
  *  
  * @return                                     traffic_selector_substructure_t object
- * 
- * @ingroup payloads
  */
 traffic_selector_substructure_t *traffic_selector_substructure_create(void);
 
 /**
- * @brief Creates an initialized traffif selector substructure using
+ * Creates an initialized traffif selector substructure using
  * the values from a traffic_selector_t.
  * 
  * @param traffic_selector     traffic_selector_t to use for initialization
  * @return                                     traffic_selector_substructure_t object
- * 
- * @ingroup payloads
  */
-traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector(traffic_selector_t *traffic_selector);
-
+traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector(
+                                                                               traffic_selector_t *traffic_selector);
 
-#endif /* /TRAFFIC_SELECTOR_SUBSTRUCTURE_H_ */
+#endif /* /TRAFFIC_SELECTOR_SUBSTRUCTURE_H_ @} */
index 066885c550a1ff601e7a93fad0fa844e100d20da..2dfb777139300824d7091b2c19db5d7ed3f735b7 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file transform_attribute.c
- * 
- * @brief Implementation of transform_attribute_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
index 30583b23fe09088fd0226ee86b40a721757121d9..32039cbafcf6736b0354638761ff634235b6916e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file transform_attribute.h
- * 
- * @brief Interface of transform_attribute_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 transform_attribute transform_attribute
+ * @{ @ingroup payloads
  */
 
 #ifndef TRANSFORM_ATTRIBUTE_H_
@@ -33,8 +33,6 @@ typedef struct transform_attribute_t transform_attribute_t;
 
 /**
  * Type of the attribute, as in IKEv2 RFC 3.3.5.
- * 
- * @ingroup payloads
  */
 enum transform_attribute_type_t {
        ATTRIBUTE_UNDEFINED = 16384,
@@ -43,17 +41,13 @@ enum transform_attribute_type_t {
 
 /** 
  * enum name for transform_attribute_type_t.
- * 
- * @ingroup payloads
  */
 extern enum_name_t *transform_attribute_type_names;
 
 /**
- * @brief Class representing an IKEv2- TRANSFORM Attribute.
+ * Class representing an IKEv2- TRANSFORM Attribute.
  * 
  * The TRANSFORM ATTRIBUTE format is described in RFC section 3.3.5.
- * 
- * @ingroup payloads
  */
 struct transform_attribute_t {
        /**
@@ -62,93 +56,79 @@ struct transform_attribute_t {
        payload_t payload_interface;
 
        /**
-        * @brief Returns the currently set value of the attribute.
+        * Returns the currently set value of the attribute.
         *      
-        * @warning Returned data are not copied.
+        * Returned data are not copied.
         * 
-        * @param this  calling transform_attribute_t object
         * @return              chunk_t pointing to the value
         */
        chunk_t (*get_value_chunk) (transform_attribute_t *this);
        
        /**
-        * @brief Returns the currently set value of the attribute.
+        * Returns the currently set value of the attribute.
         *      
-        * @warning Returned data are not copied.
+        * Returned data are not copied.
         * 
-        * @param this  calling transform_attribute_t object
         * @return              value
         */
        u_int16_t (*get_value) (transform_attribute_t *this);
        
        /**
-        * @brief Sets the value of the attribute.
+        * Sets the value of the attribute.
         *      
-        * @warning Value is getting copied.
+        * Value is getting copied.
         * 
-        * @param this  calling transform_attribute_t object
         * @param value chunk_t pointing to the value to set
         */
        void (*set_value_chunk) (transform_attribute_t *this, chunk_t value);
 
        /**
-        * @brief Sets the value of the attribute.
+        * Sets the value of the attribute.
         * 
-        * @param this  calling transform_attribute_t object
         * @param value value to set
         */
        void (*set_value) (transform_attribute_t *this, u_int16_t value);
 
        /**
-        * @brief Sets the type of the attribute.
+        * Sets the type of the attribute.
         *      
-        * @param this  calling transform_attribute_t object
         * @param type  type to set (most significant bit is set to zero)
         */
        void (*set_attribute_type) (transform_attribute_t *this, u_int16_t type);
        
        /**
-        * @brief get the type of the attribute.
+        * get the type of the attribute.
         *      
-        * @param this  calling transform_attribute_t object
         * @return              type of the value
         */
        u_int16_t (*get_attribute_type) (transform_attribute_t *this);
        
        /**
-        * @brief Clones an transform_attribute_t object.
+        * Clones an transform_attribute_t object.
         *
-        * @param this  transform_attribute_t object to clone
         * @return              cloned transform_attribute_t object
         */
        transform_attribute_t * (*clone) (transform_attribute_t *this);
 
        /**
-        * @brief Destroys an transform_attribute_t object.
-        *
-        * @param this  transform_attribute_t object to destroy
+        * Destroys an transform_attribute_t object.
         */
        void (*destroy) (transform_attribute_t *this);
 };
 
 /**
- * @brief Creates an empty transform_attribute_t object.
+ * Creates an empty transform_attribute_t object.
  * 
  * @return                             transform_attribute_t object
- * 
- * @ingroup payloads
  */
 transform_attribute_t *transform_attribute_create(void);
 
 /**
- * @brief Creates an transform_attribute_t of type KEY_LENGTH.
+ * Creates an transform_attribute_t of type KEY_LENGTH.
  * 
  * @param key_length   key length in bytes
  * @return                             transform_attribute_t object
- * 
- * @ingroup payloads
  */
 transform_attribute_t *transform_attribute_create_key_length(u_int16_t key_length);
 
-
-#endif /*TRANSFORM_ATTRIBUTE_H_*/
+#endif /*TRANSFORM_ATTRIBUTE_H_ @} */
index d64d6c75440e7bc507382a1fc860034263b3615e..6706cf8029059930881dd7592e9b1cc416573a7f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file transform_substructure.h
- * 
- * @brief Implementation of transform_substructure_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 97f587d5d5ed4b7b2fb9813ed995fe902c5de7de..0194b9904017e452ff63c9966723ccff6c81d8a8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file transform_substructure.h
- * 
- * @brief Interface of transform_substructure_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 transform_substructure transform_substructure
+ * @{ @ingroup payloads
  */
 
 #ifndef TRANSFORM_SUBSTRUCTURE_H_
@@ -39,25 +39,19 @@ typedef struct transform_substructure_t transform_substructure_t;
 
 /**
  * IKEv1 Value for a transform payload.
- * 
- * @ingroup payloads
  */
 #define TRANSFORM_TYPE_VALUE 3
 
 /**
  * Length of the transform substructure header in bytes.
- * 
- * @ingroup payloads
  */
 #define TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH 8
 
 
 /**
- * @brief Class representing an IKEv2- TRANSFORM SUBSTRUCTURE.
+ * Class representing an IKEv2- TRANSFORM SUBSTRUCTURE.
  * 
  * The TRANSFORM SUBSTRUCTURE format is described in RFC section 3.3.2.
- * 
- * @ingroup payloads
  */
 struct transform_substructure_t {
        /**
@@ -66,121 +60,105 @@ struct transform_substructure_t {
        payload_t payload_interface;
        
        /**
-        * @brief Creates an iterator of stored transform_attribute_t objects.
-        * 
-        * @warning The created iterator has to get destroyed by the caller!
+        * Creates an iterator of stored transform_attribute_t objects.
         * 
-        * @warning When deleting an transform attribute using this iterator, 
-        *                      the length of this transform substructure has to be refreshed 
-        *                      by calling get_length()!
+        * When deleting an transform attribute using this iterator, 
+        * the length of this transform substructure has to be refreshed 
+        * by calling get_length().
         *
-        * @param this                  calling transform_substructure_t object
-        * @param[in] forward   iterator direction (TRUE: front to end)
+        * @param forward               iterator direction (TRUE: front to end)
         * @return                              created iterator_t object.
         */
-       iterator_t * (*create_transform_attribute_iterator) (transform_substructure_t *this, bool forward);
+       iterator_t * (*create_transform_attribute_iterator) (
+                                                               transform_substructure_t *this, bool forward);
        
        /**
-        * @brief Adds a transform_attribute_t object to this object.
-        * 
-        * @warning The added proposal_substructure_t object  is 
-        *                      getting destroyed in destroy function of transform_substructure_t.
+        * Adds a transform_attribute_t object to this object.
         *
-        * @param this          calling transform_substructure_t object
         * @param proposal  transform_attribute_t object to add
         */
-       void (*add_transform_attribute) (transform_substructure_t *this,transform_attribute_t *attribute);
+       void (*add_transform_attribute) (transform_substructure_t *this,
+                                                                        transform_attribute_t *attribute);
        
        /**
-        * @brief Sets the next_payload field of this substructure
+        * Sets the next_payload field of this substructure
         * 
         * If this is the last transform, next payload field is set to 0,
         * otherwise to 3
         *
-        * @param this          calling transform_substructure_t object
         * @param is_last       When TRUE, next payload field is set to 0, otherwise to 3
         */
        void (*set_is_last_transform) (transform_substructure_t *this, bool is_last);
        
        /**
-        * @brief Checks if this is the last transform.
+        * Checks if this is the last transform.
         * 
-        * @param this          calling transform_substructure_t object
         * @return                      TRUE if this is the last Transform, FALSE otherwise
         */
        bool (*get_is_last_transform) (transform_substructure_t *this);
        
        /**
-        * @brief Sets transform type of the current transform substructure.
+        * Sets transform type of the current transform substructure.
         *
-        * @param this          calling transform_substructure_t object
         * @param type          type value to set
         */
-       void (*set_transform_type) (transform_substructure_t *this,u_int8_t type);
+       void (*set_transform_type) (transform_substructure_t *this, u_int8_t type);
        
        /**
-        * @brief get transform type of the current transform.
+        * get transform type of the current transform.
         * 
-        * @param this          calling transform_substructure_t object
         * @return                      Transform type of current transform substructure.
         */
        u_int8_t (*get_transform_type) (transform_substructure_t *this);
        
        /**
-        * @brief Sets transform id of the current transform substructure.
+        * Sets transform id of the current transform substructure.
         *
-        * @param this          calling transform_substructure_t object
-        * @param id                    transform id to set
+        * @param id            transform id to set
         */
-       void (*set_transform_id) (transform_substructure_t *this,u_int16_t id);
+       void (*set_transform_id) (transform_substructure_t *this, u_int16_t id);
        
        /**
-        * @brief get transform id of the current transform.
+        * get transform id of the current transform.
         * 
-        * @param this          calling transform_substructure_t object
         * @return                      Transform id of current transform substructure.
         */
        u_int16_t (*get_transform_id) (transform_substructure_t *this);
        
        /**
-        * @brief get transform id of the current transform.
+        * get transform id of the current transform.
         * 
-        * @param this                  calling transform_substructure_t object
-        * @param key_length            The key length is written to this location      
+        * @param key_length    The key length is written to this location      
         * @return                      
         *                                              - SUCCESS if a key length attribute is contained
         *                                              - FAILED if no key length attribute is part of this 
         *                                                transform or key length uses more then 16 bit!
         */
-       status_t (*get_key_length) (transform_substructure_t *this,u_int16_t *key_length);
+       status_t (*get_key_length) (transform_substructure_t *this,
+                                                               u_int16_t *key_length);
 
        /**
-        * @brief Clones an transform_substructure_t object.
+        * Clones an transform_substructure_t object.
         *
-        * @param this  transform_substructure_t object to clone
         * @return              cloned transform_substructure_t object
         */
        transform_substructure_t* (*clone) (transform_substructure_t *this);
 
        /**
-        * @brief Destroys an transform_substructure_t object.
-        *
-        * @param this  transform_substructure_t object to destroy
+        * Destroys an transform_substructure_t object.
         */
        void (*destroy) (transform_substructure_t *this);
 };
 
 /**
- * @brief Creates an empty transform_substructure_t object.
+ * Creates an empty transform_substructure_t object.
  * 
  * @return                     created transform_substructure_t object
- * 
- * @ingroup payloads
  */
 transform_substructure_t *transform_substructure_create(void);
 
 /**
- * @brief Creates an empty transform_substructure_t object.
+ * Creates an empty transform_substructure_t object.
  * 
  * The key length is used for the transport types ENCRYPTION_ALGORITHM,
  * PSEUDO_RANDOM_FUNCTION, INTEGRITY_ALGORITHM. For all 
@@ -190,9 +168,9 @@ transform_substructure_t *transform_substructure_create(void);
  * @param transform_id         transform id specifying the specific algorithm of a transform type
  * @param key_length           Key length for key lenght attribute
  * @return                                     transform_substructure_t object
- * 
- * @ingroup payloads
  */
-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);
 
-#endif /*TRANSFORM_SUBSTRUCTURE_H_*/
+#endif /*TRANSFORM_SUBSTRUCTURE_H_ @} */
index ae89919f6c9fcf2939012190d8bf2faa888fea4b..249894b3be36d3539ff9a2b1f22f7a0092f99c0b 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ts_payload.c
- * 
- * @brief Implementation of ts_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 1addee22c2615c8521dd45c78cafead7ce56debc..6f216a396869e796b5897f5d1d0e5b6e4eb2f37e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ts_payload.h
- * 
- * @brief Interface of ts_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 ts_payload ts_payload
+ * @{ @ingroup payloads
  */
 
 
@@ -35,22 +35,14 @@ typedef struct ts_payload_t ts_payload_t;
 
 /**
  * Length of a TS payload without the Traffic selectors.
- * 
- * @ingroup payloads
  */
 #define TS_PAYLOAD_HEADER_LENGTH 8
 
 
 /**
- * @brief Class representing an IKEv2 TS payload.
+ * Class representing an IKEv2 TS payload.
  *
  * The TS payload format is described in RFC section 3.13.
- *
- * @b Constructors:
- * - ts_payload_create()
- * - ts_payload_create_from_traffic_selectors()
- *
- * @ingroup payloads
  */
 struct ts_payload_t {
        /**
@@ -59,9 +51,8 @@ struct ts_payload_t {
        payload_t payload_interface;
        
        /**
-        * @brief Get the type of TSpayload (TSi or TSr).
+        * Get the type of TSpayload (TSi or TSr).
         *
-        * @param this                  calling id_payload_t object
         * @return
         *                                              - TRUE if this payload is of type TSi
         *                                              - FALSE if this payload is of type TSr
@@ -69,9 +60,8 @@ struct ts_payload_t {
        bool (*get_initiator) (ts_payload_t *this);
        
        /**
-        * @brief Set the type of TS payload (TSi or TSr).
+        * Set the type of TS payload (TSi or TSr).
         *
-        * @param this                  calling id_payload_t object
         * @param is_initiator  
         *                                              - TRUE if this payload is of type TSi
         *                                              - FALSE if this payload is of type TSr
@@ -79,75 +69,61 @@ struct ts_payload_t {
        void (*set_initiator) (ts_payload_t *this,bool is_initiator);
        
        /**
-        * @brief Adds a traffic_selector_substructure_t object to this object.
-        * 
-        * @warning The added traffic_selector_substructure_t object  is 
-        *                      getting destroyed in destroy function of ts_payload_t.
+        * Adds a traffic_selector_substructure_t object to this object.
         *
-        * @param this                          calling ts_payload_t object
         * @param traffic_selector  traffic_selector_substructure_t object to add
         */
-       void (*add_traffic_selector_substructure) (ts_payload_t *this,traffic_selector_substructure_t *traffic_selector);
+       void (*add_traffic_selector_substructure) (ts_payload_t *this,
+                                                       traffic_selector_substructure_t *traffic_selector);
        
        /**
-        * @brief Creates an iterator of stored traffic_selector_substructure_t objects.
+        * Creates an iterator of stored traffic_selector_substructure_t objects.
         * 
-        * @warning The created iterator has to get destroyed by the caller!
-        * 
-        * @warning When removing an traffic_selector_substructure_t object 
-        *                      using this iterator, the length of this payload 
-        *                      has to get refreshed by calling payload_t.get_length!
+        * When removing an traffic_selector_substructure_t object 
+        * using this iterator, the length of this payload 
+        * has to get refreshed by calling payload_t.get_length!
         *
-        * @param this                  calling ts_payload_t object
-        * @param[in] forward   iterator direction (TRUE: front to end)
+        * @param forward               iterator direction (TRUE: front to end)
         * @return                              created iterator_t object
         */
-       iterator_t *(*create_traffic_selector_substructure_iterator) (ts_payload_t *this, bool forward);
+       iterator_t *(*create_traffic_selector_substructure_iterator) (
+                                                                                       ts_payload_t *this, bool forward);
        
        /**
-        * @brief Get a list of nested traffic selectors as traffic_selector_t.
+        * Get a list of nested traffic selectors as traffic_selector_t.
         * 
         * Resulting list and its traffic selectors must be destroyed after usage
         *
-        * @param this                  calling ts_payload_t object
         * @return                              list of traffic selectors
         */
        linked_list_t *(*get_traffic_selectors) (ts_payload_t *this);
 
        /**
-        * @brief Destroys an ts_payload_t object.
-        *
-        * @param this  ts_payload_t object to destroy
+        * Destroys an ts_payload_t object.
         */
        void (*destroy) (ts_payload_t *this);
 };
 
 /**
- * @brief Creates an empty ts_payload_t object.
- * 
+ * Creates an empty ts_payload_t object.
  * 
  * @param is_initiator 
  *                                             - TRUE if this payload is of type TSi
  *                                             - FALSE if this payload is of type TSr
  * @return                             ts_payload_t object
- * 
- * @ingroup payloads
  */
 ts_payload_t *ts_payload_create(bool is_initiator);
 
 /**
- * @brief Creates ts_payload with a list of traffic_selector_t
- * 
+ * Creates ts_payload with a list of traffic_selector_t
  * 
  * @param is_initiator 
  *                                                     - TRUE if this payload is of type TSi
  *                                                     - FALSE if this payload is of type TSr
  * @param traffic_selectors    list of traffic selectors to include
  * @return                                     ts_payload_t object
- * 
- * @ingroup payloads
  */
-ts_payload_t *ts_payload_create_from_traffic_selectors(bool is_initiator, linked_list_t *traffic_selectors);
-
+ts_payload_t *ts_payload_create_from_traffic_selectors(bool is_initiator, 
+                                                                                       linked_list_t *traffic_selectors);
 
-#endif /* TS_PAYLOAD_H_ */
+#endif /* TS_PAYLOAD_H_ @} */
index bbe73608508f7e8bf321388784a4361837814409..8c09de7cda2a39f8997f98b0a446d36117dd76fd 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file unknown_payload.c
- * 
- * @brief Implementation of unknown_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index 8d13a03a3fa2eee34ef45340f3cd0571f163531e..605f192855f6386c5a4512e34dfc8b5ad94a8021 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file unknown_payload.h
- * 
- * @brief Interface of unknown_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 unknown_payload unknown_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef UNKNOWN_PAYLOAD_H_
@@ -31,22 +31,15 @@ typedef struct unknown_payload_t unknown_payload_t;
 
 /**
  * Header length of the unknown payload.
- * 
- * @ingroup payloads
  */
 #define UNKNOWN_PAYLOAD_HEADER_LENGTH 4
 
 /**
- * @brief Payload which can't be processed further.
+ * Payload which can't be processed further.
  *
  * When the parser finds an unknown payload, he builds an instance of
  * this class. This allows further processing of this payload, such as
  * a check for the critical bit in the header.
- *
- * @b Constructors:
- * - unknown_payload_create()
- *
- * @ingroup payloads
  */
 struct unknown_payload_t {
        
@@ -56,40 +49,33 @@ struct unknown_payload_t {
        payload_t payload_interface;
        
        /**
-        * @brief Get the raw data of this payload, without 
+        * Get the raw data of this payload, without 
         * the generic payload header.
         * 
         * Returned data are NOT copied and must not be freed.
         *
-        * @param this                  calling unknown_payload_t object
         * @return                              data as chunk_t
         */
        chunk_t (*get_data) (unknown_payload_t *this);
        
        /**
-        * @brief Get the critical flag.
+        * Get the critical flag.
         *
-        * @param this                  calling unknown_payload_t object
         * @return                              TRUE if payload is critical, FALSE if not
         */
        bool (*is_critical) (unknown_payload_t *this);
        
        /**
-        * @brief Destroys an unknown_payload_t object.
-        *
-        * @param this  unknown_payload_t object to destroy
+        * Destroys an unknown_payload_t object.
         */
        void (*destroy) (unknown_payload_t *this);
 };
 
 /**
- * @brief Creates an empty unknown_payload_t object.
+ * Creates an empty unknown_payload_t object.
  * 
  * @return unknown_payload_t object
- * 
- * @ingroup payloads
  */
 unknown_payload_t *unknown_payload_create(void);
 
-
-#endif /* UNKNOWN_PAYLOAD_H_ */
+#endif /* UNKNOWN_PAYLOAD_H_ @} */
index e3a4d2e1ff0131a190cb17b213a7bedfe1e26dfa..6bee953391104860acc7c3e5c4645416d59f7140 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file vendor_id_payload.c
- * 
- * @brief Implementation of vendor_id_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <stddef.h>
index c7eebc1550b3b75122b6a9f2b05bc96a3efb926c..a805a366f1da933e0675ad16ee229a24e467edd8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file vendor_id_payload.h
- * 
- * @brief Interface of vendor_id_payload_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 vendor_id_payload vendor_id_payload
+ * @{ @ingroup payloads
  */
 
 #ifndef VENDOR_ID_PAYLOAD_H_
@@ -31,21 +31,14 @@ typedef struct vendor_id_payload_t vendor_id_payload_t;
 
 /**
  * Length of a VENDOR ID payload without the VID data in bytes.
- * 
- * @ingroup payloads
  */
 #define VENDOR_ID_PAYLOAD_HEADER_LENGTH 4
 
 
 /**
- * @brief Class representing an IKEv2 VENDOR ID payload.
+ * Class representing an IKEv2 VENDOR ID payload.
  *
  * The VENDOR ID payload format is described in RFC section 3.12.
- *
- * @b Constructors:
- * - vendor_id_payload_create()
- *
- * @ingroup payloads
  */
 struct vendor_id_payload_t {
        /**
@@ -54,51 +47,43 @@ struct vendor_id_payload_t {
        payload_t payload_interface;
 
        /**
-        * @brief Set the VID data.
+        * Set the VID data.
         * 
         * Data are getting cloned.
         *
-        * @param this                  calling vendor_id_payload_t object
         * @param data                  VID data as chunk_t
         */
        void (*set_data) (vendor_id_payload_t *this, chunk_t data);
        
        /**
-        * @brief Get the VID data.
+        * Get the VID data.
         * 
         * Returned data are a copy of the internal one.
         *
-        * @param this                  calling vendor_id_payload_t object
         * @return                              VID data as chunk_t
         */
        chunk_t (*get_data_clone) (vendor_id_payload_t *this);
        
        /**
-        * @brief Get the VID data.
+        * Get the VID data.
         * 
         * Returned data are NOT copied.
         *
-        * @param this                  calling vendor_id_payload_t object
         * @return                              VID data as chunk_t
         */
        chunk_t (*get_data) (vendor_id_payload_t *this);
        
        /**
-        * @brief Destroys an vendor_id_payload_t object.
-        *
-        * @param this  vendor_id_payload_t object to destroy
+        * Destroys an vendor_id_payload_t object.
         */
        void (*destroy) (vendor_id_payload_t *this);
 };
 
 /**
- * @brief Creates an empty vendor_id_payload_t object.
+ * Creates an empty vendor_id_payload_t object.
  * 
  * @return vendor_id_payload_t object
- * 
- * @ingroup payloads
  */
 vendor_id_payload_t *vendor_id_payload_create(void);
 
-
-#endif /* VENDOR_ID_PAYLOAD_H_ */
+#endif /* VENDOR_ID_PAYLOAD_H_ @} */
index b7f6a1def45608f23d776975e0eef810a5c47c2a..88df4f3d26a59daa5365b4532cc8294bda35d987 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file kernel_interface.c
- *
- * @brief Implementation of kernel_interface_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2006-2007 Tobias Brunner
@@ -25,6 +18,8 @@
  * WITHOUT ANY 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/types.h>
index 256c207978faba9eaa449b4b41b9518d693102a7..624316d97eedc5ca33da96ad06c496e536aa7b52 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file kernel_interface.h
- *
- * @brief Interface of kernel_interface_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
  * Copyright (C) 2005-2006 Martin Willi
  * WITHOUT ANY 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 kernel_interface kernel_interface
+ * @{ @ingroup kernel
  */
 
 #ifndef KERNEL_INTERFACE_H_
@@ -37,8 +37,6 @@ typedef struct kernel_interface_t kernel_interface_t;
  * Direction of a policy. These are equal to those
  * defined in xfrm.h, but we want to stay implementation
  * neutral here.
- *
- * @ingroup kernel
  */
 enum policy_dir_t {
        /** Policy for inbound traffic */
@@ -50,7 +48,7 @@ enum policy_dir_t {
 };
 
 /**
- * @brief Interface to the kernel.
+ * Interface to the kernel.
  * 
  * The kernel interface handles the communication with the kernel
  * for SA and policy management. It allows setup of these, and provides 
@@ -59,36 +57,28 @@ enum policy_dir_t {
  * reference counting. The Linux kernel does not allow the same policy
  * installed twice, but we need this as CHILD_SA exist multiple times
  * when rekeying. Thats why we do reference counting of policies.
- *
- * @b Constructors:
- *  - kernel_interface_create()
- *
- * @ingroup kernel
  */
 struct kernel_interface_t {
 
        /**
-        * @brief Get a SPI from the kernel.
+        * Get a SPI from the kernel.
         *
         * @warning get_spi() implicitely creates an SA with
         * the allocated SPI, therefore the replace flag
         * in add_sa() must be set when installing this SA.
         * 
-        * @param this          calling object
         * @param src           source address of SA
         * @param dst           destination address of SA
         * @param protocol      protocol for SA (ESP/AH)
         * @param reqid         unique ID for this SA
-        * @param[out] spi      allocated spi
-        * @return
-        *                                      - SUCCESS
-        *                                      - FAILED if kernel comm failed
+        * @param spi           allocated spi
+        * @return                              SUCCESS if operation completed
         */
        status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst, 
                                                protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi);
        
        /**
-        * @brief Add an SA to the SAD.
+        * Add an SA to the SAD.
         * 
         * add_sa() may update an already allocated
         * SPI (via get_spi). In this case, the replace
@@ -98,7 +88,6 @@ struct kernel_interface_t {
         * gets the keys itself from the PRF, as we don't know
         * his algorithms and key sizes.
         * 
-        * @param this                  calling object
         * @param src                   source address for this SA
         * @param dst                   destination address for this SA
         * @param spi                   SPI allocated by us or remote peer
@@ -112,9 +101,7 @@ struct kernel_interface_t {
         * @param mode                  mode of the SA (tunnel, transport)
         * @param encap                 enable UDP encapsulation for NAT traversal
         * @param replace               Should an already installed SA be updated?
-        * @return
-        *                                              - SUCCESS
-        *                                              - FAILED if kernel comm failed
+        * @return                              SUCCESS if operation completed
         */
        status_t (*add_sa) (kernel_interface_t *this,
                                                host_t *src, host_t *dst, u_int32_t spi,
@@ -125,14 +112,13 @@ struct kernel_interface_t {
                                                bool update);
        
        /**
-        * @brief Update the hosts on an installed SA.
+        * Update the hosts on an installed SA.
         *
         * We cannot directly update the destination address as the kernel
         * requires the spi, the protocol AND the destination address (and family)
         * to identify SAs. Therefore if the destination address changed we
         * create a new SA and delete the old one.
         *
-        * @param this                  calling object
         * @param spi                   SPI of the SA
         * @param protocol              protocol for this SA (ESP/AH)
         * @param src                   current source address
@@ -140,9 +126,7 @@ struct kernel_interface_t {
         * @param new_src               new source address
         * @param new_dst               new destination address
         * @param encap                 use UDP encapsulation
-        * @return
-        *                                              - SUCCESS
-        *                                              - FAILED if kernel comm failed
+        * @return                              SUCCESS if operation completed
         */
        status_t (*update_sa)(kernel_interface_t *this,
                                                  u_int32_t spi, protocol_id_t protocol,
@@ -150,44 +134,37 @@ struct kernel_interface_t {
                                                  host_t *new_src, host_t *new_dst, bool encap);
        
        /**
-        * @brief Query the use time of an SA.
+        * Query the use time of an SA.
         *
         * The use time of an SA is not the time of the last usage, but 
         * the time of the first usage of the SA.
         * 
-        * @param this                  calling object
         * @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[out] use_time the time of this SA's last use
-        * @return
-        *                                              - SUCCESS
-        *                                              - FAILED if kernel comm failed
+        * @param use_time              pointer receives the time of this SA's last use
+        * @return                              SUCCESS if operation completed
         */
        status_t (*query_sa) (kernel_interface_t *this, host_t *dst, u_int32_t spi, 
                                                  protocol_id_t protocol, u_int32_t *use_time);
        
        /**
-        * @brief Delete a previusly installed SA from the SAD.
+        * Delete a previusly installed SA from the SAD.
         * 
-        * @param this                  calling object
         * @param dst                   destination address for this SA
         * @param spi                   SPI allocated by us or remote peer
         * @param protocol              protocol for this SA (ESP/AH)
-        * @return
-        *                                              - SUCCESS
-        *                                              - FAILED if kernel comm failed
+        * @return                              SUCCESS if operation completed
         */
        status_t (*del_sa) (kernel_interface_t *this, host_t *dst, u_int32_t spi,
                                                protocol_id_t protocol);
        
        /**
-        * @brief Add a policy to the SPD.
+        * Add a policy to the SPD.
         * 
         * A policy is always associated to an SA. Traffic which matches a
         * policy is handled by the SA with the same reqid.
         * 
-        * @param this                  calling object
         * @param src                   source address of SA
         * @param dst                   dest address of SA
         * @param src_ts                traffic selector to match traffic source
@@ -197,9 +174,7 @@ struct kernel_interface_t {
         * @param reqid                 uniqe ID of an SA to use to enforce policy
         * @param high_prio             if TRUE, uses a higher priority than any with FALSE
         * @param mode                  mode of SA (tunnel, transport)
-        * @return
-        *                                              - SUCCESS
-        *                                              - FAILED if kernel comm failed
+        * @return                              SUCCESS if operation completed
         */
        status_t (*add_policy) (kernel_interface_t *this,
                                                        host_t *src, host_t *dst,
@@ -209,19 +184,16 @@ struct kernel_interface_t {
                                                        u_int32_t reqid, bool high_prio, mode_t mode);
        
        /**
-        * @brief Query the use time of a policy.
+        * Query the use time of a policy.
         *
         * The use time of a policy is the time the policy was used
         * for the last time.
         * 
-        * @param this                  calling object
         * @param src_ts                traffic selector to match traffic source
         * @param dst_ts                traffic selector to match traffic dest
         * @param direction             direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
         * @param[out] use_time the time of this SA's last use
-        * @return
-        *                                              - SUCCESS
-        *                                              - FAILED if kernel comm failed
+        * @return                              SUCCESS if operation completed
         */
        status_t (*query_policy) (kernel_interface_t *this,
                                                          traffic_selector_t *src_ts, 
@@ -229,20 +201,17 @@ struct kernel_interface_t {
                                                          policy_dir_t direction, u_int32_t *use_time);
        
        /**
-        * @brief Remove a policy from the SPD.
+        * Remove a policy from the SPD.
         *
         * The kernel interface implements reference counting for policies.
         * If the same policy is installed multiple times (in the case of rekeying),
         * the reference counter is increased. del_policy() decreases the ref counter
         * and removes the policy only when no more references are available.
         *
-        * @param this                  calling object
         * @param src_ts                traffic selector to match traffic source
         * @param dst_ts                traffic selector to match traffic dest
         * @param direction             direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
-        * @return
-        *                                              - SUCCESS
-        *                                              - FAILED if kernel comm failed
+        * @return                              SUCCESS if operation completed
         */
        status_t (*del_policy) (kernel_interface_t *this,
                                                        traffic_selector_t *src_ts, 
@@ -250,82 +219,69 @@ struct kernel_interface_t {
                                                        policy_dir_t direction);
        
        /**
-        * @brief Get our outgoing source address for a destination.
+        * Get our outgoing source address for a destination.
         *
         * Does a route lookup to get the source address used to reach dest.
         * The returned host is allocated and must be destroyed.
         *
-        * @param this                  calling object
         * @param dest                  target destination address
         * @return                              outgoing source address, NULL if unreachable
         */
        host_t* (*get_source_addr)(kernel_interface_t *this, host_t *dest);
        
        /**
-        * @brief Get the interface name of a local address.
+        * Get the interface name of a local address.
         *
-        * @param this                  calling object
         * @param host                  address to get interface name from
         * @return                              allocated interface name, or NULL if not found
         */
        char* (*get_interface) (kernel_interface_t *this, host_t *host);
        
        /**
-        * @brief Creates an iterator over all local addresses.
+        * Creates an iterator over all local addresses.
         *
         * This function blocks an internal cached address list until the
         * iterator gets destroyed.
         * These hosts are read-only, do not modify or free.
         *
-        * @param this                  calling object
         * @return                              iterator over host_t's
         */
        iterator_t *(*create_address_iterator) (kernel_interface_t *this);
        
        /**
-        * @brief Add a virtual IP to an interface.
+        * Add a virtual IP to an interface.
         *
         * Virtual IPs are attached to an interface. If an IP is added multiple
         * times, the IP is refcounted and not removed until del_ip() was called
         * as many times as add_ip().
         * The virtual IP is attached to the interface where the iface_ip is found.
         *
-        * @param this                  calling object
         * @param virtual_ip    virtual ip address to assign
         * @param iface_ip              IP of an interface to attach virtual IP
-        * @return
-        *                                              - SUCCESS
-        *                                              - FAILED if kernel comm failed
+        * @return                              SUCCESS if operation completed
         */
        status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip,
                                                host_t *iface_ip);
        
        /**
-        * @brief Remove a virtual IP from an interface.
+        * Remove a virtual IP from an interface.
         *
         * The kernel interface uses refcounting, see add_ip().
         *
-        * @param this                  calling object
         * @param virtual_ip    virtual ip address to assign
-        * @return
-        *                                              - SUCCESS
-        *                                              - FAILED if kernel comm failed
+        * @return                              SUCCESS if operation completed
         */
        status_t (*del_ip) (kernel_interface_t *this, host_t *virtual_ip);
        
        /**
-        * @brief Destroys a kernel_interface object.
-        *
-        * @param kernel_interface_t    calling object
+        * Destroys a kernel_interface object.
         */
        void (*destroy) (kernel_interface_t *kernel_interface);
 };
 
 /**
- * @brief Creates an object of type kernel_interface_t.
- * 
- * @ingroup kernel
+ * Creates an object of type kernel_interface_t.
  */
 kernel_interface_t *kernel_interface_create(void);
 
-#endif /*KERNEL_INTERFACE_H_*/
+#endif /*KERNEL_INTERFACE_H_ @} */
index f2fa91569a1e9997502d2e1a07974544533925ec..fb5f9920fa0f13d0bbc71d787bb2d371bfefaa52 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file packet.c
- * 
- * @brief Implementation of packet_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 "packet.h"
 
-
 typedef struct private_packet_t private_packet_t;
 
 /**
index acf953032527c54b5de0e892545e81a41d14c2e5..c9818be6f85d566ea299009cce742480267e6115 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file packet.h
- * 
- * @brief Interface of packet_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 packet packet
+ * @{ @ingroup network
  */
 
 #ifndef PACKET_H_
@@ -30,105 +30,88 @@ typedef struct packet_t packet_t;
 #include <utils/host.h>
 
 /**
- * @brief Abstraction of an UDP-Packet, contains data, sender and receiver.
- *
- * @b Constructors:
- * - packet_create()
- *
- * @ingroup network
+ * Abstraction of an UDP-Packet, contains data, sender and receiver.
  */
 struct packet_t {
 
        /**
-        * @brief Set the source address.
+        * Set the source address.
         * 
         * Set host_t is now owned by packet_t, it will destroy
         * it if necessary.
         * 
-        * @param this          calling object
         * @param source        address to set as source
         */
        void (*set_source) (packet_t *packet, host_t *source);
        
        /**
-        * @brief Set the destination address.
+        * Set the destination address.
         * 
         * Set host_t is now owned by packet_t, it will destroy
         * it if necessary.
         * 
-        * @param this          calling object
         * @param source        address to set as destination
         */
        void (*set_destination) (packet_t *packet, host_t *destination);
        
        /**
-        * @brief Get the source address.
+        * Get the source address.
         * 
         * Set host_t is still owned by packet_t, clone it
         * if needed.
         * 
-        * @param this          calling object
         * @return                      source address
         */
        host_t *(*get_source) (packet_t *packet);
        
        /**
-        * @brief Get the destination address.
+        * Get the destination address.
         * 
         * Set host_t is still owned by packet_t, clone it
         * if needed.
         * 
-        * @param this          calling object
         * @return                      destination address
         */
        host_t *(*get_destination) (packet_t *packet);
        
        /**
-        * @brief Get the data from the packet.
+        * Get the data from the packet.
         * 
         * The data pointed by the chunk is still owned 
         * by the packet. Clone it if needed.
         * 
-        * @param this          calling object
         * @return                      chunk containing the data
         */
        chunk_t (*get_data) (packet_t *packet);
        
        /**
-        * @brief Set the data in the packet.
+        * Set the data in the packet.
         * 
         * Supplied chunk data is now owned by the 
         * packet. It will free it.
         * 
-        * @param this          calling object
         * @param data          chunk with data to set
         */
        void (*set_data) (packet_t *packet, chunk_t data);
        
        /**
-        * @brief Clones a packet_t object.
+        * Clones a packet_t object.
         *  
-        * @param packet        calling object
-        * @param clone         pointer to a packet_t object pointer where the new object is stored
+        * @param clone         clone of the packet
         */
        packet_t* (*clone) (packet_t *packet);
        
        /**
-        * @brief Destroy the packet, freeing contained data.
-        *  
-        * @param packet        packet to destroy       
+        * Destroy the packet, freeing contained data.
         */
        void (*destroy) (packet_t *packet);
 };
 
 /**
- * @brief create an empty packet
+ * create an empty packet
  *  
  * @return packet_t object
- * 
- * @ingroup network
  */
 packet_t *packet_create(void);
 
-
-#endif /*PACKET_H_*/
+#endif /*PACKET_H_ @} */
index 1de1dd3d23963aec7959e4b1b957b91eb54d4d2c..2f3bf6cb228f9384a3b45dfa1658925b587b38aa 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file receiver.c
- *
- * @brief Implementation of receiver_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
@@ -33,9 +28,8 @@
 #include <processing/jobs/job.h>
 #include <processing/jobs/process_message_job.h>
 #include <processing/jobs/callback_job.h>
+#include <crypto/hashers/hasher.h>
 
-/** length of the full cookie, including time (u_int32_t + SHA1()) */
-#define COOKIE_LENGTH 24
 /** lifetime of a cookie, in seconds */
 #define COOKIE_LIFETIME 10
 /** how many times to reuse the secret */
@@ -145,11 +139,12 @@ static chunk_t cookie_build(private_receiver_t *this, message_t *message,
 {
        u_int64_t spi = message->get_initiator_spi(message);
        host_t *ip = message->get_source(message);
-       chunk_t input, hash = chunk_alloca(this->hasher->get_hash_size(this->hasher));
+       chunk_t input, hash;
        
        /* COOKIE = t | sha1( IPi | SPIi | t | secret ) */
        input = chunk_cata("cccc", ip->get_address(ip), chunk_from_thing(spi),
                                          chunk_from_thing(t), secret);
+       hash = chunk_alloca(this->hasher->get_hash_size(this->hasher));
        this->hasher->get_hash(this->hasher, input, hash.ptr);
        return chunk_cat("cc", chunk_from_thing(t), hash);
 }
@@ -167,7 +162,8 @@ static bool cookie_verify(private_receiver_t *this, message_t *message,
        now = time(NULL);
        t = *(u_int32_t*)cookie.ptr;
 
-       if (cookie.len != COOKIE_LENGTH || 
+       if (cookie.len != sizeof(u_int32_t) +
+                       this->hasher->get_hash_size(this->hasher) || 
                t < now - this->secret_offset - COOKIE_LIFETIME)
        {
                DBG2(DBG_NET, "received cookie lifetime expired, rejecting");
@@ -212,7 +208,8 @@ static bool cookie_required(private_receiver_t *this, message_t *message)
                packet_t *packet = message->get_packet(message);
                chunk_t data = packet->get_data(packet);
                if (data.len < 
-                        IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH + COOKIE_LENGTH ||
+                        IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH +
+                        sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher) ||
                        *(data.ptr + 16) != NOTIFY || 
                        *(u_int16_t*)(data.ptr + IKE_HEADER_LENGTH + 6) != htons(COOKIE))
                {
@@ -222,7 +219,7 @@ static bool cookie_required(private_receiver_t *this, message_t *message)
                else
                {
                        data.ptr += IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH;
-                       data.len = COOKIE_LENGTH;
+                       data.len = sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher);
                        if (!cookie_verify(this, message, data))
                        {
                                DBG2(DBG_NET, "found cookie, but content invalid");
@@ -351,8 +348,14 @@ receiver_t *receiver_create()
 
        this->public.destroy = (void(*)(receiver_t*)) destroy;
        
+       this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED);
+       if (this->hasher == NULL)
+       {
+               DBG1(DBG_NET, "creating cookie hasher failed, no hashers supported");
+               free(this);
+               return NULL;
+       }
        this->randomizer = randomizer_create();
-       this->hasher = hasher_create(HASH_SHA1);
        this->secret_switch = now;
        this->secret_offset = random() % now;
        this->secret_used = 0;
index 1bfa7b764498ed5c3a459b25f733afca9fe62ee1..00315490acda27bb76165e1b410ebe11cf0b2b5e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file receiver.h
- *
- * @brief Interface of receiver_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 receiver receiver
+ * @{ @ingroup network
  */
 
 #ifndef RECEIVER_H_
@@ -30,7 +30,7 @@ typedef struct receiver_t receiver_t;
 #include <utils/host.h>
 
 /**
- * @brief Receives packets from the socket and adds them to the job queue.
+ * Receives packets from the socket and adds them to the job queue.
  * 
  * The receiver starts a thread, wich reads on the blocking socket. A received
  * packet is preparsed and a process_message_job is queued in the job queue.
@@ -50,32 +50,23 @@ typedef struct receiver_t receiver_t;
  * 
  * Further, the number of half-initiated IKE_SAs is limited per peer. This
  * mades it impossible for a peer to flood the server with its real IP address.
- * 
- * @b Constructors:
- *  - receiver_create()
- * 
- * @ingroup network
  */
 struct receiver_t {
        
        /**
-        * @brief Destroys a receiver_t object.
-        *
-        * @param receiver      receiver object
+        * Destroys a receiver_t object.
         */
        void (*destroy) (receiver_t *receiver);
 };
 
 /**
- * @brief Create a receiver_t object.
+ * Create a receiver_t object.
  * 
  * The receiver thread will start working, get data
  * from the socket and add those packets to the job queue.
  * 
- * @return     receiver_t object
- * 
- * @ingroup network
+ * @return     receiver_t object, NULL if initialization fails
  */
 receiver_t * receiver_create(void);
 
-#endif /*RECEIVER_H_*/
+#endif /*RECEIVER_H_ @} */
index f934dc5092090f5e6612607db571b803b8dea045..942401a8268d977da19cf68c980806e61bb92a6a 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file sender.c
- *
- * @brief Implementation of sender_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
index 8d611cc9030433c87401e9da8724c5c2d3fc46ba..6b62dcc97f165a97bdabd36d5aff1170373ea053 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file sender.h
- *
- * @brief Interface of sender_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 sender sender
+ * @{ @ingroup network
  */
 
 #ifndef SENDER_H_
@@ -30,45 +30,35 @@ typedef struct sender_t sender_t;
 #include <network/packet.h>
 
 /**
- * @brief Thread responsible for sending packets over the socket.
- * 
- * @b Constructors:
- *  - sender_create()
- * 
- * @ingroup network
+ * Thread responsible for sending packets over the socket.
  */
 struct sender_t {
        
        /**
-        * @brief Send a packet over the network.
+        * Send a packet over the network.
         *
         * This function is non blocking and adds the packet to a queue.
         * Whenever the sender thread thinks it's good to send the packet,
         * it'll do so.
         *
-        * @param this          calling object
         * @param packet        packet to send
         */
        void (*send) (sender_t *this, packet_t *packet);
        
        /**
-        * @brief Destroys a sender object.
-        *
-        * @param this          calling object
+        * Destroys a sender object.
         */
        void (*destroy) (sender_t *this);
 };
 
 /**
- * @brief Create the sender thread.
+ * Create the sender thread.
  * 
  * The thread will start to work, getting packets
  * from its queue and sends them out.
  * 
  * @return             created sender object
- * 
- * @ingroup network
  */
 sender_t * sender_create(void);
 
-#endif /*SENDER_H_*/
+#endif /*SENDER_H_ @} */
index 3b76ae57034b39d6ea26c49fda8715789c2c7fc8..72ee6bbcaa1b279f62604d0ea4554314dd104ab7 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file socket.c
- *
- * @brief Implementation of socket_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
  * Copyright (C) 2005-2006 Martin Willi
@@ -20,6 +13,8 @@
  * WITHOUT ANY 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 <pthread.h>
index a4c407579a057e29126e1bd4ba214d1bff920cc4..cedfc089079ccd3ff5197701994fe9e1796a062c 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file socket.c
- *
- * @brief Implementation of socket_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
  * Copyright (C) 2005-2007 Martin Willi
@@ -20,6 +13,8 @@
  * WITHOUT ANY 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 <pthread.h>
index 4d825132509df6b6e16108a56ecd9da07a0b474a..7ddde619016edb6ef8fb7be0dd62af1f2adc6a20 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file socket.h
- * 
- * @brief Interface for socket_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
  * Copyright (C) 2005-2006 Martin Willi
  * WITHOUT ANY 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 socket socket
+ * @{ @ingroup network
  */
 
 #ifndef SOCKET_H_
@@ -33,38 +33,36 @@ typedef struct socket_t socket_t;
 #include <utils/linked_list.h>
 
 /**
- * @brief Maximum size of a packet.
- *
- * 3000 Bytes should be sufficient, see IKEv2 RFC.
+ * Maximum size of a packet.
  *
- * @ingroup network
+ * 3000 Bytes should be sufficient, see IKEv2 RFC. However, we currently
+ * do not support HASH_AND_URL certificates, so we require to transmit
+ * the full certificates. To run our multi-CA test with 2 intermediate CAs,
+ * 5000 bytes is sufficient.
  */
-#define MAX_PACKET 3000
+#define MAX_PACKET 5000
 
 /**
- * @brief Abstraction of all sockets (IPv6/IPv6 send/receive).
+ * Abstraction of all sockets (IPv4/IPv6 send/receive).
  *
  * All available sockets are bound and the receive function
- * reads from them. To allow binding of other daemons (pluto) to
- * UDP/500, this implementation uses RAW sockets. An installed
- * "Linux socket filter" filters out all non-IKEv2 traffic and handles
- * just IKEv2 messages. An other daemon (pluto) must handle all traffic
- * seperatly, e.g. ignore IKEv2 traffic, since charon handles that. 
- * 
- * @b Constructors:
- * - socket_create()
- * 
- * @ingroup network
+ * reads from them. There are actually two implementations:
+ * The first uses raw sockets to allow binding of other daemons (pluto) to
+ * UDP/500. An installed "Linux socket filter" filters out all non-IKEv2 
+ * traffic and handles just IKEv2 messages. An other daemon (pluto) must 
+ * handle all traffic seperatly, e.g. ignore IKEv2 traffic, since charon 
+ * handles that.
+ * The other implementation uses normal sockets and is built if
+ * --disable-pluto is given to the configure script.
  */
 struct socket_t {
        
        /**
-        * @brief Receive a packet.
+        * Receive a packet.
         * 
         * Reads a packet from the socket and sets source/dest
         * appropriately.
         * 
-        * @param this                  socket_t object to work on
         * @param packet                pinter gets address from allocated packet_t
         * @return                              
         *                                              - SUCCESS when packet successfully received
@@ -73,14 +71,13 @@ struct socket_t {
        status_t (*receive) (socket_t *this, packet_t **packet);
        
        /**
-        * @brief Send a packet.
+        * Send a packet.
         * 
         * Sends a packet to the net using destination from the packet.
         * Packet is sent using default routing mechanisms, thus the 
         * source address in packet is ignored.
         * 
-        * @param this                  socket_t object to work on
-        * @param packet[out]   packet_t to send
+        * @param packet                packet_t to send
         * @return                              
         *                                              - SUCCESS when packet successfully sent
         *                                              - FAILED when unable to send
@@ -88,23 +85,16 @@ struct socket_t {
        status_t (*send) (socket_t *this, packet_t *packet);
        
        /**
-        * @brief Destroy sockets.
-        * 
-        * close sockets and destroy socket_t object
-        * 
-        * @param this                  socket_t to destroy
+        * Destroy socket.
         */
        void (*destroy) (socket_t *this);
 };
 
 /**
- * @brief Create a socket_t, wich binds multiple sockets.
+ * Create a socket_t, wich binds multiple sockets.
  *
  * @return                             socket_t object
- *
- * @ingroup network
  */
 socket_t *socket_create();
 
-
-#endif /*SOCKET_H_*/
+#endif /*SOCKET_H_ @} */
diff --git a/src/charon/plugins/dbus/Makefile.am b/src/charon/plugins/dbus/Makefile.am
new file mode 100644 (file)
index 0000000..ccfada4
--- /dev/null
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon ${dbus_CFLAGS}
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libcharon-dbus.la
+
+libcharon_dbus_la_SOURCES = dbus.h dbus.c
+libcharon_dbus_la_LDFLAGS = -module
+libcharon_dbus_la_LIBADD = ${dbus_LIBS}
+
similarity index 82%
rename from src/charon/control/interfaces/dbus_interface.c
rename to src/charon/plugins/dbus/dbus.c
index 39226aaefa0f0df1f6ce405c522e7308f69a42ad..ac29db773ff6a91901c0cdc5f9dbe5ce5085ddfa 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file dbus_interface.c
- * 
- * @brief Implementation of dbus_interface_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 DBUS_API_SUBJECT_TO_CHANGE
@@ -26,7 +21,7 @@
 #include <NetworkManager/NetworkManagerVPN.h>
 #include <stdlib.h>
 
-#include "dbus_interface.h"
+#include "dbus.h"
 
 #include <library.h>
 #include <daemon.h>
 
 
 #define NM_DBUS_SERVICE_STRONG "org.freedesktop.NetworkManager.strongswan"
-#define NM_DBUS_INTERFACE_STRONG "org.freedesktop.NetworkManager.strongswan"
+#define NM_dbus_STRONG "org.freedesktop.NetworkManager.strongswan"
 #define NM_DBUS_PATH_STRONG "/org/freedesktop/NetworkManager/strongswan"
 
-typedef struct private_dbus_interface_t private_dbus_interface_t;
+typedef struct private_dbus_t private_dbus_t;
 
 /**
- * Private data of an dbus_interface_t object.
+ * Private data of an dbus_t object.
  */
-struct private_dbus_interface_t {
+struct private_dbus_t {
 
        /**
         * Public part of dbus_t object.
         */
-       dbus_interface_t public;
+       dbus_t public;
        
        /**
         * DBUS connection
@@ -78,11 +73,11 @@ struct private_dbus_interface_t {
 /**
  * set daemon state and send StateChange signal to the bus
  */
-static void set_state(private_dbus_interface_t *this, NMVPNState state)
+static void set_state(private_dbus_t *this, NMVPNState state)
 {
        DBusMessage* msg;
 
-       msg = dbus_message_new_signal(NM_DBUS_PATH_STRONG, NM_DBUS_INTERFACE_STRONG, NM_DBUS_VPN_SIGNAL_STATE_CHANGE);
+       msg = dbus_message_new_signal(NM_DBUS_PATH_STRONG, NM_dbus_STRONG, NM_DBUS_VPN_SIGNAL_STATE_CHANGE);
 
        if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &this->state,
                                                          DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID) ||
@@ -122,7 +117,7 @@ static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
 /**
  * process NetworkManagers startConnection method call
  */
-static bool start_connection(private_dbus_interface_t *this, DBusMessage* msg)
+static bool start_connection(private_dbus_t *this, DBusMessage* msg)
 {
        DBusMessage *reply, *signal;
        char *name, *user, **data, **passwords, **routes;
@@ -156,8 +151,8 @@ static bool start_connection(private_dbus_interface_t *this, DBusMessage* msg)
                child_cfg = get_child_from_peer(peer_cfg, name);
                if (child_cfg)
                {
-                       status = charon->interfaces->initiate(charon->interfaces,
-                                               peer_cfg, child_cfg, interface_manager_cb_empty, NULL);
+                       status = charon->controller->initiate(charon->controller,
+                                               peer_cfg, child_cfg, controller_cb_empty, NULL);
                }
                else
                {
@@ -173,7 +168,7 @@ static bool start_connection(private_dbus_interface_t *this, DBusMessage* msg)
        
                set_state(this, NM_VPN_STATE_STARTED);
                signal = dbus_message_new_signal(NM_DBUS_PATH_STRONG,
-                                                                                NM_DBUS_INTERFACE_STRONG,
+                                                                                NM_dbus_STRONG,
                                                                                 NM_DBUS_VPN_SIGNAL_IP4_CONFIG);
                me = other = p2p = mss = netmask = 0;
                dev = domain = banner = "";
@@ -205,7 +200,7 @@ static bool start_connection(private_dbus_interface_t *this, DBusMessage* msg)
 /**
  * process NetworkManagers stopConnection method call
  */
-static bool stop_connection(private_dbus_interface_t *this, DBusMessage* msg)
+static bool stop_connection(private_dbus_t *this, DBusMessage* msg)
 {
        u_int32_t id;
        iterator_t *iterator;
@@ -220,7 +215,7 @@ static bool stop_connection(private_dbus_interface_t *this, DBusMessage* msg)
        
        set_state(this, NM_VPN_STATE_STOPPING);
        
-       iterator = charon->interfaces->create_ike_sa_iterator(charon->interfaces);
+       iterator = charon->controller->create_ike_sa_iterator(charon->controller);
        while (iterator->iterate(iterator, (void**)&ike_sa))
        {
                child_sa_t *child_sa;
@@ -230,7 +225,7 @@ static bool stop_connection(private_dbus_interface_t *this, DBusMessage* msg)
                {
                        id = ike_sa->get_unique_id(ike_sa);
                        iterator->destroy(iterator);
-                       charon->interfaces->terminate_ike(charon->interfaces, id, NULL, NULL);
+                       charon->controller->terminate_ike(charon->controller, id, NULL, NULL);
                        set_state(this, NM_VPN_STATE_STOPPED);
                        return TRUE;;
                }
@@ -242,7 +237,7 @@ static bool stop_connection(private_dbus_interface_t *this, DBusMessage* msg)
                                id = child_sa->get_reqid(child_sa);
                                children->destroy(children);
                                iterator->destroy(iterator);
-                               charon->interfaces->terminate_child(charon->interfaces, id, NULL, NULL);
+                               charon->controller->terminate_child(charon->controller, id, NULL, NULL);
                                set_state(this, NM_VPN_STATE_STOPPED);
                                return TRUE;
                        }
@@ -257,7 +252,7 @@ static bool stop_connection(private_dbus_interface_t *this, DBusMessage* msg)
 /**
  * process NetworkManagers getState method call
  */
-static bool get_state(private_dbus_interface_t *this, DBusMessage* msg)
+static bool get_state(private_dbus_t *this, DBusMessage* msg)
 {
        DBusMessage* reply;
        reply = dbus_message_new_method_return(msg);
@@ -275,21 +270,21 @@ static bool get_state(private_dbus_interface_t *this, DBusMessage* msg)
  * Handle incoming messages
  */
 static DBusHandlerResult message_handler(DBusConnection *con, DBusMessage *msg,
-                                                                                private_dbus_interface_t *this)
+                                                                                private_dbus_t *this)
 {
        bool handled;
 
-       if (dbus_message_is_method_call(msg, NM_DBUS_INTERFACE_STRONG,
+       if (dbus_message_is_method_call(msg, NM_dbus_STRONG,
                                                                        "startConnection"))
        {
                handled = start_connection(this, msg);
        }
-       else if (dbus_message_is_method_call(msg, NM_DBUS_INTERFACE_STRONG,
+       else if (dbus_message_is_method_call(msg, NM_dbus_STRONG,
                                                                                 "stopConnection"))
        {
                handled = stop_connection(this, msg);
        }
-       else if (dbus_message_is_method_call(msg, NM_DBUS_INTERFACE_STRONG,
+       else if (dbus_message_is_method_call(msg, NM_dbus_STRONG,
                                                                                 "getState"))
        {
                handled = get_state(this, msg);
@@ -312,11 +307,11 @@ static DBusHandlerResult message_handler(DBusConnection *con, DBusMessage *msg,
  * Handle received signals
 
 static DBusHandlerResult signal_handler(DBusConnection *con, DBusMessage *msg,
-                                                                               private_dbus_interface_t *this)
+                                                                               private_dbus_t *this)
 {
        bool handled;
 
-       if (dbus_message_is_signal(msg, NM_DBUS_INTERFACE, "VPNConnectionStateChange"))
+       if (dbus_message_is_signal(msg, NM_dbus, "VPNConnectionStateChange"))
        {
                NMVPNState state;
                char *name;
@@ -344,7 +339,7 @@ static DBusHandlerResult signal_handler(DBusConnection *con, DBusMessage *msg,
 /**
  * dispatcher function processed by a seperate thread
  */
-static job_requeue_t dispatch(private_dbus_interface_t *this)
+static job_requeue_t dispatch(private_dbus_t *this)
 {
        if (dbus_connection_read_write_dispatch(this->conn, -1))
        {
@@ -356,7 +351,7 @@ static job_requeue_t dispatch(private_dbus_interface_t *this)
 /**
  * Implementation of interface_t.destroy.
  */
-static void destroy(private_dbus_interface_t *this)
+static void destroy(private_dbus_t *this)
 {
        this->job->cancel(this->job);
        dbus_connection_close(this->conn);
@@ -369,13 +364,13 @@ static void destroy(private_dbus_interface_t *this)
 /*
  * Described in header file
  */
-interface_t *interface_create()
+plugin_t *plugin_create()
 {
        int ret;
        DBusObjectPathVTable v = {NULL, (void*)&message_handler, NULL, NULL, NULL, NULL};
-       private_dbus_interface_t *this = malloc_thing(private_dbus_interface_t);
+       private_dbus_t *this = malloc_thing(private_dbus_t);
   
-       this->public.interface.destroy = (void (*)(interface_t*))destroy;
+       this->public.plugin.destroy = (void (*)(plugin_t*))destroy;
        
        dbus_error_init(&this->err); 
        this->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &this->err);
@@ -408,7 +403,7 @@ interface_t *interface_create()
        }
        
        dbus_bus_add_match(this->conn, "type='signal', "
-                                          "interface='" NM_DBUS_INTERFACE_VPN "',"
+                                          "interface='" NM_dbus_VPN "',"
                                           "path='" NM_DBUS_PATH_VPN "'", &this->err);
        if (dbus_error_is_set (&this->err))
        {
@@ -422,6 +417,6 @@ interface_t *interface_create()
        this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL);
        charon->processor->queue_job(charon->processor, (job_t*)this->job);
 
-       return &this->public.interface;
+       return &this->public.plugin;
 }
 
diff --git a/src/charon/plugins/dbus/dbus.h b/src/charon/plugins/dbus/dbus.h
new file mode 100644 (file)
index 0000000..e5bc2d2
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup dbus dbus
+ * @ingroup cplugins
+ *
+ * @defgroup dbus_i dbus
+ * @{ @ingroup dbus
+ */
+
+#ifndef DBUS_H_
+#define DBUS_H_
+
+#include <plugins/plugin.h>
+
+typedef struct dbus_t dbus_t;
+
+/**
+ * NetworkManager DBUS control plugin.
+ *
+ * This plugin uses a DBUS connection. It is designed to work in conjuction
+ * with NetworkManager to configure and control the daemon.
+ */
+struct dbus_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a dbus plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* DBUS_H_ @}*/
diff --git a/src/charon/plugins/eap_aka/Makefile.am b/src/charon/plugins/eap_aka/Makefile.am
new file mode 100644 (file)
index 0000000..c938716
--- /dev/null
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libcharon-eapaka.la
+
+libcharon_eapaka_la_SOURCES = eap_aka_plugin.h eap_aka_plugin.c eap_aka.h eap_aka.c
+libcharon_eapaka_la_LDFLAGS = -module
+libcharon_eapaka_la_LIBADD = -lgmp
+
similarity index 81%
rename from src/charon/sa/authenticators/eap/eap_aka.c
rename to src/charon/plugins/eap_aka/eap_aka.c
index 8fb1f85cd42e9015e9aa7591be9463effe0bbd98..3dd842b9ef1f0486b9b96f5f0f770571b6ec0b86 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_aka.c
- *
- * @brief Implementation of eap_aka_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
+ *
+ * $Id$
  */
 
 
@@ -44,6 +39,7 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <time.h>
+#include <gmp.h>
 
 #include "eap_aka.h"
 
@@ -51,7 +47,6 @@
 #include <library.h>
 #include <utils/randomizer.h>
 #include <crypto/hashers/hasher.h>
-#include <crypto/prfs/fips_prf.h>
 
 /* Use test vectors specified in S.S0055
 #define TEST_VECTORS */
 #define F5                       0x47
 #define F5STAR           0x48
 
+typedef enum aka_subtype_t aka_subtype_t;
+typedef enum aka_attribute_t aka_attribute_t;
+
+/**
+ * Subtypes of AKA messages
+ */
+enum aka_subtype_t {
+       AKA_CHALLENGE = 1,
+       AKA_AUTHENTICATION_REJECT = 2,
+       AKA_SYNCHRONIZATION_FAILURE = 4,
+       AKA_IDENTITY = 5,
+       AKA_NOTIFICATION = 12,
+       AKA_REAUTHENTICATION = 13,
+       AKA_CLIENT_ERROR = 14,
+};
+
+/**
+ * Attribute types in AKA messages
+ */
+enum aka_attribute_t {
+       /** defines the end of attribute list */
+       AT_END = -1,
+       AT_RAND = 1,
+       AT_AUTN = 2,
+       AT_RES = 3,
+       AT_AUTS = 4,
+       AT_PADDING = 6,
+       AT_NONCE_MT = 7,
+       AT_PERMANENT_ID_REQ = 10,
+       AT_MAC = 11,
+       AT_NOTIFICATION = 12,
+       AT_ANY_ID_REQ = 13,
+       AT_IDENTITY = 14,
+       AT_VERSION_LIST = 15,
+       AT_SELECTED_VERSION = 16,
+       AT_FULLAUTH_ID_REQ = 17,
+       AT_COUNTER = 19,
+       AT_COUNTER_TOO_SMALL = 20,
+       AT_NONCE_S = 21,
+       AT_CLIENT_ERROR_CODE = 22,
+       AT_IV = 129,
+       AT_ENCR_DATA = 130,
+       AT_NEXT_PSEUDONYM = 132,
+       AT_NEXT_REAUTH_ID = 133,
+       AT_CHECKCODE = 134,
+       AT_RESULT_IND = 135,
+};
+
 ENUM_BEGIN(aka_subtype_names, AKA_CHALLENGE, AKA_IDENTITY,
        "AKA_CHALLENGE",
        "AKA_AUTHENTICATION_REJECT",
@@ -155,6 +198,26 @@ struct private_eap_aka_t {
         */
        identification_t *peer;
        
+       /**
+        * SHA11 hasher
+        */
+       hasher_t *sha1;
+       
+       /**
+        * SHA1_NOFINAL hasher for G() function
+        */
+       hasher_t *sha1_nof;
+       
+       /**
+        * MAC function used in EAP-AKA
+        */
+       signer_t *signer;
+       
+       /**
+        * pseudo random function used in EAP-aka
+        */
+       prf_t *prf;
+       
        /**
         * Key for EAP MAC
         */
@@ -347,7 +410,7 @@ static void mpz_mod_poly(mpz_t r, mpz_t a, mpz_t b)
  * Step 4 of the various fx() functions:
  * Polynomial whiten calculations
  */
-static void step4(u_int8_t x[])
+static void step4(private_eap_aka_t *this, u_int8_t x[])
 {
        mpz_t xm, am, bm, gm;
        
@@ -373,11 +436,38 @@ static void step4(u_int8_t x[])
        mpz_clear(gm);
 }
 
+/**
+ * Implementation of the G() function based on SHA1
+ */
+static void g_sha1(private_eap_aka_t *this,
+                                  u_int8_t t[], chunk_t c, u_int8_t res[])
+{
+       u_int8_t buf[64];
+       
+       if (c.len < sizeof(buf))
+       {
+               /* pad c with zeros */
+               memset(buf, 0, sizeof(buf));
+               memcpy(buf, c.ptr, c.len);
+               c.ptr = buf;
+               c.len = sizeof(buf);
+       }
+       else
+       {
+               /* not more than 512 bits can be G()-ed */
+               c.len = sizeof(buf);
+       }
+       
+       /* calculate the special (HASH_SHA1_STATE) hash*/
+       this->sha1_nof->get_hash(this->sha1_nof, c, res);
+}
+
 /**
  * Step 3 of the various fx() functions:
  * XOR the key into the SHA1 IV
  */
-static void step3(chunk_t k, chunk_t payload, u_int8_t h[])
+static void step3(private_eap_aka_t *this,
+                                 chunk_t k, chunk_t payload, u_int8_t h[])
 {
        u_int8_t iv[] = {
                0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA,
@@ -388,13 +478,14 @@ static void step3(chunk_t k, chunk_t payload, u_int8_t h[])
        memxor(iv, k.ptr, k.len);
        
        /* hash it with the G() function defined in FIPS 186-2 from fips_prf.h */
-       g_sha1(iv, payload, h);
+       g_sha1(this, iv, payload, h);
 }
 
 /**
  * Calculation function for f2(), f3(), f4()
  */
-static void fx(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
+static void fx(private_eap_aka_t *this,
+                          u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
 {
        chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
        u_int8_t h[HASH_SIZE_SHA1];
@@ -412,8 +503,8 @@ static void fx(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
                payload.ptr[35] ^= i;
                payload.ptr[51] ^= i;
                
-               step3(k, payload, h);
-               step4(h);
+               step3(this, k, payload, h);
+               step4(this, h);
                memcpy(out + i * 8, h, 8);
        }
 }
@@ -421,7 +512,8 @@ static void fx(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
 /**
  * Calculation function of f1() and f1star()
  */
-static void f1x(u_int8_t f, chunk_t k, chunk_t rand, chunk_t sqn,
+static void f1x(private_eap_aka_t *this,
+                               u_int8_t f, chunk_t k, chunk_t rand, chunk_t sqn,
                                chunk_t amf, u_int8_t mac[])
 {
        /* generate MAC = f1(FMK, SQN, RAND, AMF)
@@ -438,15 +530,16 @@ static void f1x(u_int8_t f, chunk_t k, chunk_t rand, chunk_t sqn,
        memxor(payload.ptr + 34, sqn.ptr, sqn.len);
        memxor(payload.ptr + 42, amf.ptr, amf.len);
        
-       step3(k, payload, h);
-       step4(h);
+       step3(this, k, payload, h);
+       step4(this, h);
        memcpy(mac, h, MAC_LENGTH);
 }
 
 /**
  * Calculation function of f5() and f5star()
  */
-static void f5x(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t ak[])
+static void f5x(private_eap_aka_t *this, 
+                               u_int8_t f, chunk_t k, chunk_t rand, u_int8_t ak[])
 {
        chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
        u_int8_t h[HASH_SIZE_SHA1];
@@ -456,81 +549,81 @@ static void f5x(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t ak[])
        memxor(payload.ptr + 12, fmk.ptr, fmk.len);
        memxor(payload.ptr + 16, rand.ptr, rand.len);
        
-       step3(k, payload, h);
-       step4(h);
+       step3(this, k, payload, h);
+       step4(this, h);
        memcpy(ak, h, AK_LENGTH);
 }
 
 /**
  * Calculate the MAC from a RAND, SQN, AMF value using K
  */
-static void f1(chunk_t k, chunk_t rand, chunk_t sqn, chunk_t amf, u_int8_t mac[])
+static void f1(private_eap_aka_t *this, chunk_t k, chunk_t rand, chunk_t sqn,
+                          chunk_t amf, u_int8_t mac[])
 {
-       f1x(F1, k, rand, sqn, amf, mac);
+       f1x(this, F1, k, rand, sqn, amf, mac);
        DBG3(DBG_IKE, "MAC %b", mac, MAC_LENGTH);
 }
 
 /**
  * Calculate the MACS from a RAND, SQN, AMF value using K
  */
-static void f1star(chunk_t k, chunk_t rand, chunk_t sqn, chunk_t amf, u_int8_t macs[])
+static void f1star(private_eap_aka_t *this, chunk_t k, chunk_t rand,
+                                  chunk_t sqn, chunk_t amf, u_int8_t macs[])
 {
-       f1x(F1STAR, k, rand, sqn, amf, macs);
+       f1x(this, F1STAR, k, rand, sqn, amf, macs);
        DBG3(DBG_IKE, "MACS %b", macs, MAC_LENGTH);
 }
 
 /**
  * Calculate RES from RAND using K
  */
-static void f2(chunk_t k, chunk_t rand, u_int8_t res[])
+static void f2(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t res[])
 {
-       fx(F2, k, rand, res);
+       fx(this, F2, k, rand, res);
        DBG3(DBG_IKE, "RES %b", res, RES_LENGTH);
 }
 
 /**
  * Calculate CK from RAND using K
  */
-static void f3(chunk_t k, chunk_t rand, u_int8_t ck[])
+static void f3(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t ck[])
 {
-       fx(F3, k, rand, ck);
+       fx(this, F3, k, rand, ck);
        DBG3(DBG_IKE, "CK %b", ck, CK_LENGTH);
 }
 
 /**
  * Calculate IK from RAND using K
  */
-static void f4(chunk_t k, chunk_t rand, u_int8_t ik[])
+static void f4(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t ik[])
 {
-       fx(F4, k, rand, ik);
+       fx(this, F4, k, rand, ik);
        DBG3(DBG_IKE, "IK %b", ik, IK_LENGTH);
 }
 
 /**
  * Calculate AK from a RAND using K
  */
-static void f5(chunk_t k, chunk_t rand, u_int8_t ak[])
+static void f5(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t ak[])
 {
-       f5x(F5, k, rand, ak);
+       f5x(this, F5, k, rand, ak);
        DBG3(DBG_IKE, "AK %b", ak, AK_LENGTH);
 }
 
 /**
  * Calculate AKS from a RAND using K
  */
-static void f5star(chunk_t k, chunk_t rand, u_int8_t aks[])
+static void f5star(private_eap_aka_t *this, chunk_t k, chunk_t rand, u_int8_t aks[])
 {
-       f5x(F5STAR, k, rand, aks);
+       f5x(this, F5STAR, k, rand, aks);
        DBG3(DBG_IKE, "AKS %b", aks, AK_LENGTH);
 }
 
 /**
  * derive the keys needed for EAP_AKA
  */
-static void derive_keys(private_eap_aka_t *this, identification_t *id)
+static bool derive_keys(private_eap_aka_t *this, identification_t *id)
 {
-       hasher_t *hasher;
-       prf_t *prf;
        chunk_t ck, ik, mk, identity, tmp;
        
        ck = chunk_alloca(CK_LENGTH);
@@ -539,26 +632,22 @@ static void derive_keys(private_eap_aka_t *this, identification_t *id)
        identity = id->get_encoding(id);
        
        /* MK = SHA1( Identity | IK | CK ) */
-       f3(this->k, this->rand, ck.ptr);
-       f4(this->k, this->rand, ik.ptr);
+       f3(this, this->k, this->rand, ck.ptr);
+       f4(this, this->k, this->rand, ik.ptr);
        DBG3(DBG_IKE, "Identity %B", &identity);
        tmp = chunk_cata("ccc", identity, ik, ck);
        DBG3(DBG_IKE, "Identity|IK|CK %B", &tmp);
-       hasher = hasher_create(HASH_SHA1);
-       hasher->get_hash(hasher, tmp, mk.ptr);
-       hasher->destroy(hasher);
+       this->sha1->get_hash(this->sha1, tmp, mk.ptr);
        
        /* K_encr | K_auth | MSK | EMSK = prf(0) | prf(0)
         * FIPS PRF has 320 bit block size, we need 160 byte for keys
         *  => run prf four times */
-       prf = prf_create(PRF_FIPS_SHA1_160);
-       prf->set_key(prf, mk);
-       tmp = chunk_alloca(prf->get_block_size(prf) * 4);
-       prf->get_bytes(prf, chunk_empty, tmp.ptr);
-       prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 1);
-       prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 2);
-       prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 3);
-       prf->destroy(prf);
+       this->prf->set_key(this->prf, mk);
+       tmp = chunk_alloca(this->prf->get_block_size(this->prf) * 4);
+       this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr);
+       this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * 1);
+       this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * 2);
+       this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * 3);
        chunk_free(&this->k_encr);
        chunk_free(&this->k_auth);
        chunk_free(&this->msk);
@@ -571,6 +660,7 @@ static void derive_keys(private_eap_aka_t *this, identification_t *id)
        DBG3(DBG_IKE, "K_auth %B", &this->k_auth);
        DBG3(DBG_IKE, "MSK %B", &this->msk);
        DBG3(DBG_IKE, "EMSK %B", &this->emsk);
+       return TRUE;
 }
 
 /*
@@ -582,18 +672,21 @@ static void derive_keys(private_eap_aka_t *this, identification_t *id)
  */
 static status_t load_key(identification_t *me, identification_t *other, chunk_t *k)
 {
-       chunk_t shared_key;
+       shared_key_t *shared;
+       chunk_t key;
 
-       if (charon->credentials->get_eap_key(charon->credentials, me,
-                                                                                other, &shared_key) != SUCCESS)
+       shared = charon->credentials->get_shared(charon->credentials, SHARED_EAP,
+                                                                                        me, other);
+       if (shared == NULL)
        {
                return NOT_FOUND;
        }
+       key = shared->get_key(shared);
        chunk_free(k);
        *k = chunk_alloc(K_LENGTH);
        memset(k->ptr, '\0', k->len);
-       memcpy(k->ptr, shared_key.ptr, min(shared_key.len, k->len));
-       chunk_free(&shared_key);
+       memcpy(k->ptr, key.ptr, min(key.len, k->len));
+       shared->destroy(shared);
        return SUCCESS;
 }
 
@@ -739,13 +832,11 @@ static eap_payload_t *build_aka_payload(private_eap_aka_t *this, eap_code_t code
        /* create MAC if AT_MAC attribte was included */
        if (mac_pos)
        {
-               signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
-               signer->set_key(signer, this->k_auth);
+               this->signer->set_key(this->signer, this->k_auth);
                DBG3(DBG_IKE, "AT_MAC signature of %B", &message);
                DBG3(DBG_IKE, "using key %B", &this->k_auth);
-               signer->get_signature(signer, message, mac_pos);
+               this->signer->get_signature(this->signer, message, mac_pos);
                DBG3(DBG_IKE, "is %b", mac_pos, AT_MAC_LENGTH);
-               signer->destroy(signer);
        }
        
        /* payload constructor takes data with some bytes skipped */
@@ -758,7 +849,8 @@ static eap_payload_t *build_aka_payload(private_eap_aka_t *this, eap_code_t code
 /**
  * Initiate a AKA-Challenge using SQN
  */
-static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn, eap_payload_t **out)
+static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn,
+                                                                                 eap_payload_t **out)
 {
        randomizer_t *randomizer;
        status_t status;
@@ -808,14 +900,14 @@ static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn,
 #      endif /* TEST_VECTORS */
        
        /* generate MAC */
-       f1(this->k, this->rand, sqn, amf, mac.ptr);
+       f1(this, this->k, this->rand, sqn, amf, mac.ptr);
        
        /* generate AK */
-       f5(this->k, this->rand, ak.ptr);
+       f5(this, this->k, this->rand, ak.ptr);
        
        /* precalculate XRES as expected from client */
        this->xres = chunk_alloc(RES_LENGTH);
-       f2(this->k, this->rand, this->xres.ptr);
+       f2(this, this->k, this->rand, this->xres.ptr);
        
        /* calculate AUTN = (SQN xor AK) || AMF || MAC */
        autn = chunk_cata("ccc", sqn, amf, mac);
@@ -896,7 +988,7 @@ static status_t server_process_synchronize(private_eap_aka_t *this,
        
        chunk_split(auts, "mm", SQN_LENGTH, &sqn, MAC_LENGTH, &macs);
        aks = chunk_alloca(AK_LENGTH);
-       f5star(this->k, this->rand, aks.ptr);
+       f5star(this, this->k, this->rand, aks.ptr);
        /* decrypt serial number by XORing AKS */
        memxor(sqn.ptr, aks.ptr, aks.len);
        
@@ -905,7 +997,7 @@ static status_t server_process_synchronize(private_eap_aka_t *this,
        amf = chunk_alloca(AMF_LENGTH);
        /* an AMF of zero is used for MACS calculation */
        memset(amf.ptr, 0, amf.len);
-       f1star(this->k, this->rand, sqn, amf, xmacs.ptr);
+       f1star(this, this->k, this->rand, sqn, amf, xmacs.ptr);
        if (!chunk_equals(macs, xmacs))
        {
                DBG1(DBG_IKE, "received MACS does not match XMACS");
@@ -974,14 +1066,10 @@ static status_t server_process_challenge(private_eap_aka_t *this, eap_payload_t
        
        /* verify EAP message MAC AT_MAC */
        {
-               bool valid;
-               signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
-               signer->set_key(signer, this->k_auth);
+               this->signer->set_key(this->signer, this->k_auth);
                DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
                DBG3(DBG_IKE, "using key %B", &this->k_auth);
-               valid = signer->verify_signature(signer, message, at_mac);
-               signer->destroy(signer);
-               if (!valid)
+               if (!this->signer->verify_signature(this->signer, message, at_mac))
                {
                        DBG1(DBG_IKE, "MAC in AT_MAC attribute verification failed");
                        return FAILED;
@@ -1135,7 +1223,7 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
 #      endif /* TEST_VECTORS */
        
        /* calculate anonymity key AK */
-       f5(this->k, this->rand, ak.ptr);
+       f5(this, this->k, this->rand, ak.ptr);
        DBG3(DBG_IKE, "using rand %B", &this->rand);
        DBG3(DBG_IKE, "using ak %B", &ak);
        /* XOR AK into SQN to decrypt it */
@@ -1147,7 +1235,7 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
        DBG3(DBG_IKE, "using sqn %B", &sqn);
        
        /* calculate expected MAC and compare against received one */
-       f1(this->k, this->rand, sqn, amf, xmac.ptr);
+       f1(this, this->k, this->rand, sqn, amf, xmac.ptr);
        if (!chunk_equals(mac, xmac))
        {
                *out = build_aka_payload(this, EAP_RESPONSE, identifier,
@@ -1171,9 +1259,9 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
                /* AMF is set to zero in AKA_SYNCHRONIZATION_FAILURE */
                memset(amf.ptr, 0, amf.len);            
                /* AKS = f5*(RAND) */
-               f5star(this->k, this->rand, aks.ptr);
+               f5star(this, this->k, this->rand, aks.ptr);
                /* MACS = f1*(RAND) */
-               f1star(this->k, this->rand, peer_sqn, amf, macs.ptr);
+               f1star(this, this->k, this->rand, peer_sqn, amf, macs.ptr);
                /* AUTS = SQN xor AKS | MACS */
                memxor(aks.ptr, peer_sqn.ptr, aks.len);
                auts = chunk_cata("cc", aks, macs);
@@ -1190,33 +1278,25 @@ static status_t peer_process_challenge(private_eap_aka_t *this,
 
        /* derive K_encr, K_auth, MSK, EMSK  */
        derive_keys(this, this->peer);
-                               
+       
        /* verify EAP message MAC AT_MAC */
+       DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
+       DBG3(DBG_IKE, "using key %B", &this->k_auth);
+       if (!this->signer->verify_signature(this->signer, message, at_mac))
        {
-               bool valid;
-               signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
-               signer->set_key(signer, this->k_auth);
-               
-               DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
-               DBG3(DBG_IKE, "using key %B", &this->k_auth);
-               valid = signer->verify_signature(signer, message, at_mac);
-               signer->destroy(signer);
-               if (!valid)
-               {
-                       *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
-                                                       AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
-                       DBG1(DBG_IKE, "MAC in AT_MAC attribute verification "
-                                "failed, sending %N %d", aka_attribute_names,
-                                AT_CLIENT_ERROR_CODE, 0);
-                       return NEED_MORE;
-               }
+               *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+                                               AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+               DBG1(DBG_IKE, "MAC in AT_MAC attribute verification "
+                        "failed, sending %N %d", aka_attribute_names,
+                        AT_CLIENT_ERROR_CODE, 0);
+               return NEED_MORE;
        }
        
        /* update stored SQN to the received one */
        memcpy(peer_sqn.ptr, sqn.ptr, sqn.len);
        
        /* calculate RES */
-       f2(this->k, this->rand, res.ptr);
+       f2(this, this->k, this->rand, res.ptr);
        
        /* build response */
        *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CHALLENGE,
@@ -1387,6 +1467,10 @@ static bool is_mutual(private_eap_aka_t *this)
  */
 static void destroy(private_eap_aka_t *this)
 {
+       DESTROY_IF(this->sha1);
+       DESTROY_IF(this->sha1_nof);
+       DESTROY_IF(this->signer);
+       DESTROY_IF(this->prf);
        chunk_free(&this->k_encr);
        chunk_free(&this->k_auth);
        chunk_free(&this->msk);
@@ -1397,29 +1481,16 @@ static void destroy(private_eap_aka_t *this)
        free(this);
 }
 
-/*
- * Described in header.
+/**
+ * generic constructor used by client & server
  */
-eap_aka_t *eap_create(eap_role_t role,
-                                         identification_t *server, identification_t *peer)
+static private_eap_aka_t *eap_aka_create_generic(identification_t *server,
+                                                                                                identification_t *peer)
 {
        private_eap_aka_t *this = malloc_thing(private_eap_aka_t);
        
-       /* public functions */
-       switch (role)
-       {
-               case EAP_SERVER:
-                       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))server_initiate;
-                       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))server_process;
-                       break;
-               case EAP_PEER:
-                       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))peer_initiate;
-                       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process;
-                       break;
-               default:
-                       free(this);
-                       return NULL;
-       }
+       this->public.eap_method_interface.initiate = NULL;
+       this->public.eap_method_interface.process = NULL;
        this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
        this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
        this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
@@ -1436,5 +1507,51 @@ eap_aka_t *eap_create(eap_role_t role,
        this->k = chunk_empty;
        this->rand = chunk_empty;
        
-       return &this->public;
+       this->sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+       this->sha1_nof = lib->crypto->create_hasher(lib->crypto, HASH_SHA1_NOFINAL);
+       this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128);
+       this->prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
+
+       if (!this->sha1 || !this->sha1_nof || !this->signer || !this->prf)
+       {
+               DBG1(DBG_IKE, "unable to initiate EAP-AKA, FIPS-PRF/SHA1 not supported");
+               DESTROY_IF(this->sha1);
+               DESTROY_IF(this->sha1_nof);
+               DESTROY_IF(this->signer);
+               DESTROY_IF(this->prf);
+               destroy(this);
+               return NULL;
+       }
+       return this;
+}
+
+/*
+ * Described in header.
+ */
+eap_aka_t *eap_aka_create_server(identification_t *server, identification_t *peer)
+{
+       private_eap_aka_t *this = eap_aka_create_generic(server, peer);
+       
+       if (this)
+       {
+               this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))server_initiate;
+               this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))server_process;
+       }
+       return (eap_aka_t*)this;
 }
+
+/*
+ * Described in header.
+ */
+eap_aka_t *eap_aka_create_peer(identification_t *server, identification_t *peer)
+{
+       private_eap_aka_t *this = eap_aka_create_generic(server, peer);
+       
+       if (this)
+       {
+               this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))peer_initiate;
+               this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process;
+       }
+       return (eap_aka_t*)this;                        
+}
+
similarity index 59%
rename from src/charon/sa/authenticators/eap/eap_aka.h
rename to src/charon/plugins/eap_aka/eap_aka.h
index a886863beae8717fdad6e3ffa7826fba5a2cf4d2..1ee8496b2d5dd2ee17a2741aca10633c67035059 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file eap_aka.h
- *
- * @brief Interface of eap_aka_t.
- *
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 eap_aka_i eap_aka
+ * @{ @ingroup eap_aka
  */
 
 #ifndef EAP_AKA_H_
 #define EAP_AKA_H_
 
 typedef struct eap_aka_t eap_aka_t;
-typedef enum aka_subtype_t aka_subtype_t;
-typedef enum aka_attribute_t aka_attribute_t;
 
 #include <sa/authenticators/eap/eap_method.h>
 
-
-/**
- * Subtypes of AKA messages
- */
-enum aka_subtype_t {
-       AKA_CHALLENGE = 1,
-       AKA_AUTHENTICATION_REJECT = 2,
-       AKA_SYNCHRONIZATION_FAILURE = 4,
-       AKA_IDENTITY = 5,
-       AKA_NOTIFICATION = 12,
-       AKA_REAUTHENTICATION = 13,
-       AKA_CLIENT_ERROR = 14,
-};
-
-/**
- * enum names for aka_subtype_t
- */
-extern enum_name_t *aka_subtype_names;
-
-/**
- * Attribute types in AKA messages
- */
-enum aka_attribute_t {
-       /** defines the end of attribute list */
-       AT_END = -1,
-       AT_RAND = 1,
-       AT_AUTN = 2,
-       AT_RES = 3,
-       AT_AUTS = 4,
-       AT_PADDING = 6,
-       AT_NONCE_MT = 7,
-       AT_PERMANENT_ID_REQ = 10,
-       AT_MAC = 11,
-       AT_NOTIFICATION = 12,
-       AT_ANY_ID_REQ = 13,
-       AT_IDENTITY = 14,
-       AT_VERSION_LIST = 15,
-       AT_SELECTED_VERSION = 16,
-       AT_FULLAUTH_ID_REQ = 17,
-       AT_COUNTER = 19,
-       AT_COUNTER_TOO_SMALL = 20,
-       AT_NONCE_S = 21,
-       AT_CLIENT_ERROR_CODE = 22,
-       AT_IV = 129,
-       AT_ENCR_DATA = 130,
-       AT_NEXT_PSEUDONYM = 132,
-       AT_NEXT_REAUTH_ID = 133,
-       AT_CHECKCODE = 134,
-       AT_RESULT_IND = 135,
-};
-
-/**
- * enum names for aka_attribute_t
- */
-extern enum_name_t *aka_attribute_names;
-
 /**  check SEQ values as client for validity, disabled by default */
 #ifndef SEQ_CHECK
 # define SEQ_CHECK 0
 #endif
 
 /**
- * @brief Implementation of the eap_method_t interface using EAP-AKA.
+ * Implementation of the eap_method_t interface using EAP-AKA.
  *
  * EAP-AKA uses 3rd generation mobile phone standard authentication
  * mechanism for authentication. It is a mutual authentication
@@ -111,12 +53,6 @@ extern enum_name_t *aka_attribute_names;
  * any SEQ numbers. This allows an attacker to do replay attacks. But since
  * the server has proven his identity via IKE, such an attack is only
  * possible between server and AAA (if any).
- *
- * @b Constructors:
- *  - eap_aka_create()
- *  - eap_client_create() using eap_method EAP_AKA
- *
- * @ingroup eap
  */
 struct eap_aka_t {
 
@@ -127,15 +63,21 @@ struct eap_aka_t {
 };
 
 /**
- * @brief Creates the EAP method EAP-AKA.
+ * Creates the server implementation of the EAP method EAP-AKA.
  *
  * @param server       ID of the EAP server
  * @param peer         ID of the EAP client
  * @return                     eap_aka_t object
+ */
+eap_aka_t *eap_aka_create_server(identification_t *server, identification_t *peer);
+
+/**
+ * Creates the peer implementation of the EAP method EAP-AKA.
  *
- * @ingroup eap
+ * @param server       ID of the EAP server
+ * @param peer         ID of the EAP client
+ * @return                     eap_aka_t object
  */
-eap_aka_t *eap_create(eap_role_t role,
-                                         identification_t *server, identification_t *peer);
+eap_aka_t *eap_aka_create_peer(identification_t *server, identification_t *peer);
 
-#endif /* EAP_AKA_H_ */
+#endif /* EAP_AKA_H_ @}*/
diff --git a/src/charon/plugins/eap_aka/eap_aka_plugin.c b/src/charon/plugins/eap_aka/eap_aka_plugin.c
new file mode 100644 (file)
index 0000000..1975d6f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "eap_aka_plugin.h"
+
+#include "eap_aka.h"
+
+#include <daemon.h>
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(eap_aka_plugin_t *this)
+{
+       charon->eap->remove_method(charon->eap,
+                                                          (eap_constructor_t)eap_aka_create_server);
+       charon->eap->remove_method(charon->eap,
+                                                          (eap_constructor_t)eap_aka_create_peer);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       eap_aka_plugin_t *this = malloc_thing(eap_aka_plugin_t);
+       
+       this->plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_SERVER,
+                                                       (eap_constructor_t)eap_aka_create_server);
+       charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_PEER,
+                                                       (eap_constructor_t)eap_aka_create_peer);
+       
+       return &this->plugin;
+}
+
diff --git a/src/charon/plugins/eap_aka/eap_aka_plugin.h b/src/charon/plugins/eap_aka/eap_aka_plugin.h
new file mode 100644 (file)
index 0000000..07fcc82
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup eap_aka eap_aka
+ * @ingroup cplugins
+ *
+ * @defgroup eap_aka_plugin eap_aka_plugin
+ * @{ @ingroup eap_aka
+ */
+
+#ifndef EAP_AKA_PLUGIN_H_
+#define EAP_AKA_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_aka_plugin_t eap_aka_plugin_t;
+
+/**
+ * EAP-AKA plugin
+ */
+struct eap_aka_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a eap_aka_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* EAP_AKA_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/eap_identity/Makefile.am b/src/charon/plugins/eap_identity/Makefile.am
new file mode 100644 (file)
index 0000000..1ce2426
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libcharon-eapidentity.la
+libcharon_eapidentity_la_SOURCES = \
+  eap_identity_plugin.h eap_identity_plugin.c eap_identity.h eap_identity.c
+libcharon_eapidentity_la_LDFLAGS = -module
+
similarity index 87%
rename from src/charon/sa/authenticators/eap/eap_identity.c
rename to src/charon/plugins/eap_identity/eap_identity.c
index 12a8bf7cc28bb6eb2962e12b3d5daaf340d0f15d..f6835c7f2963e5ffcefbf146b93bc49dce453542 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_identity.c
- *
- * @brief Implementation of eap_identity_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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_identity.h"
@@ -76,8 +71,9 @@ static status_t initiate(private_eap_identity_t *this, eap_payload_t **out)
 /**
  * Implementation of eap_method_t.get_type.
  */
-static eap_type_t get_type(private_eap_identity_t *this)
+static eap_type_t get_type(private_eap_identity_t *this, u_int32_t *vendor)
 {
+       *vendor = 0;
        return EAP_IDENTITY;
 }
 
@@ -108,22 +104,15 @@ static void destroy(private_eap_identity_t *this)
 /*
  * Described in header.
  */
-eap_identity_t *eap_create(eap_role_t role,
-                                                  identification_t *server, identification_t *peer)
+eap_identity_t *eap_identity_create_peer(identification_t *server,
+                                                                                identification_t *peer)
 {
-       private_eap_identity_t *this;
-       
-       if (role != EAP_PEER)
-       {
-               return NULL;
-       }
-       
-       this = malloc_thing(private_eap_identity_t);
+       private_eap_identity_t *this = malloc_thing(private_eap_identity_t);
        
        /* public functions */
        this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate;
        this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process;
-       this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*))get_type;
+       this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
        this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
        this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
        this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
@@ -133,3 +122,4 @@ eap_identity_t *eap_create(eap_role_t role,
        
        return &this->public;
 }
+
similarity index 66%
rename from src/charon/sa/authenticators/eap/eap_identity.h
rename to src/charon/plugins/eap_identity/eap_identity.h
index 20f0f0b671b7a57ad189c260a78e80ca4a559b56..5d297f7985773be465a657205216af57f55bcabf 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file eap_identity.h
- *
- * @brief Interface of eap_identity_t.
- *
- */
-
 /*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 eap_identity_i eap_identity
+ * @{ @ingroup eap_identity
  */
 
 #ifndef EAP_IDENTITY_H_
@@ -28,13 +28,7 @@ typedef struct eap_identity_t eap_identity_t;
 #include <sa/authenticators/eap/eap_method.h>
 
 /**
- * @brief Implementation of the eap_method_t interface using EAP Identity.
- *
- * @b Constructors:
- *  - eap_identity_create()
- *  - eap_client_create() using eap_method EAP_IDENTITY
- *
- * @ingroup eap
+ * Implementation of the eap_method_t interface using EAP Identity.
  */
 struct eap_identity_t {
 
@@ -45,15 +39,13 @@ struct eap_identity_t {
 };
 
 /**
- * @brief Creates the EAP method EAP Identity.
+ * Creates the EAP method EAP Identity, acting as peer.
  *
  * @param server       ID of the EAP server
  * @param peer         ID of the EAP client
  * @return                     eap_identity_t object
- *
- * @ingroup eap
  */
-eap_identity_t *eap_create(eap_role_t role,
-                                                  identification_t *server, identification_t *peer);
+eap_identity_t *eap_identity_create_peer(identification_t *server,
+                                                                                identification_t *peer);
 
-#endif /* EAP_IDENTITY_H_ */
+#endif /* EAP_IDENTITY_H_ @}*/
diff --git a/src/charon/plugins/eap_identity/eap_identity_plugin.c b/src/charon/plugins/eap_identity/eap_identity_plugin.c
new file mode 100644 (file)
index 0000000..22a884a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "eap_identity_plugin.h"
+
+#include "eap_identity.h"
+
+#include <daemon.h>
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(eap_identity_plugin_t *this)
+{
+       charon->eap->remove_method(charon->eap,
+                                                          (eap_constructor_t)eap_identity_create_peer);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       eap_identity_plugin_t *this = malloc_thing(eap_identity_plugin_t);
+       
+       this->plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       charon->eap->add_method(charon->eap, EAP_IDENTITY, 0, EAP_PEER,
+                                                       (eap_constructor_t)eap_identity_create_peer);
+       
+       return &this->plugin;
+}
+
diff --git a/src/charon/plugins/eap_identity/eap_identity_plugin.h b/src/charon/plugins/eap_identity/eap_identity_plugin.h
new file mode 100644 (file)
index 0000000..d41c141
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup eap_identity eap_identity
+ * @ingroup cplugins
+ *
+ * @defgroup eap_identity_plugin eap_identity_plugin
+ * @{ @ingroup eap_identity
+ */
+
+#ifndef EAP_IDENTITY_PLUGIN_H_
+#define EAP_IDENTITY_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_identity_plugin_t eap_identity_plugin_t;
+
+/**
+ * EAP-IDENTITY plugin.
+ */
+struct eap_identity_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a eap_identity_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* EAP_IDENTITY_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/eap_md5/Makefile.am b/src/charon/plugins/eap_md5/Makefile.am
new file mode 100644 (file)
index 0000000..2d6d68f
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libcharon-eapmd5.la
+
+libcharon_eapmd5_la_SOURCES = eap_md5_plugin.h eap_md5_plugin.c eap_md5.h eap_md5.c
+libcharon_eapmd5_la_LDFLAGS = -module
+
similarity index 78%
rename from src/charon/sa/authenticators/eap/eap_md5.c
rename to src/charon/plugins/eap_md5/eap_md5.c
index 0ca9fc566db753f2baf11bf54545376782981a38..702042f37ad21ecce38c72bdd9f648e1bd1b56c8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_md5.c
- *
- * @brief Implementation of eap_md5_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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_md5.h"
 
 #include <daemon.h>
 #include <library.h>
+#include <crypto/hashers/hasher.h>
 
 typedef struct private_eap_md5_t private_eap_md5_t;
 
@@ -85,20 +81,28 @@ struct eap_md5_header_t {
  * Hash the challenge string, create response
  */
 static status_t hash_challenge(private_eap_md5_t *this, chunk_t *response)
-{
-       chunk_t concat, secret;
+{      
+       shared_key_t *shared;
+       chunk_t concat;
        hasher_t *hasher;
-       
-       if (charon->credentials->get_eap_key(charon->credentials, this->server,
-                                                                                this->peer, &secret) != SUCCESS)
+
+       shared = charon->credentials->get_shared(charon->credentials, SHARED_EAP,
+                                                                                        this->server, this->peer);
+       if (shared == NULL)
        {
                DBG1(DBG_IKE, "no EAP key found for hosts '%D' - '%D'",
                         this->server, this->peer);
                return NOT_FOUND;
        }
-       concat = chunk_cata("cmc", chunk_from_thing(this->identifier),  
-                                               secret, this->challenge);
-       hasher = hasher_create(HASH_MD5);
+       concat = chunk_cata("ccc", chunk_from_thing(this->identifier),  
+                                               shared->get_key(shared), this->challenge);
+       shared->destroy(shared);
+       hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
+       if (hasher == NULL)
+       {
+               DBG1(DBG_IKE, "EAP-MD5 failed, MD5 not supported");
+               return FAILED;
+       }
        hasher->allocate_hash(hasher, concat, response);
        hasher->destroy(hasher);
        return SUCCESS;
@@ -244,29 +248,16 @@ static void destroy(private_eap_md5_t *this)
        free(this);
 }
 
-/*
- * Described in header.
+/**
+ * Generic constructor
  */
-eap_md5_t *eap_create(eap_role_t role,
-                                         identification_t *server, identification_t *peer)
+static private_eap_md5_t *eap_md5_create_generic(identification_t *server,
+                                                                                                identification_t *peer)
 {
        private_eap_md5_t *this = malloc_thing(private_eap_md5_t);
        
-       /* public functions */
-       switch (role)
-       {
-               case EAP_SERVER:
-                       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
-                       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server;
-                       break;
-               case EAP_PEER:
-                       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
-                       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer;
-                       break;
-               default:
-                       free(this);
-                       return NULL;
-       }
+       this->public.eap_method_interface.initiate = NULL;
+       this->public.eap_method_interface.process = NULL;
        this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
        this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
        this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
@@ -278,5 +269,32 @@ eap_md5_t *eap_create(eap_role_t role,
        this->challenge = chunk_empty;
        this->identifier = random();
        
+       return this;
+}
+
+/*
+ * see header
+ */
+eap_md5_t *eap_md5_create_server(identification_t *server, identification_t *peer)
+{
+       private_eap_md5_t *this = eap_md5_create_generic(server, peer);
+       
+       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
+       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server;
+
+       return &this->public;
+}
+
+/*
+ * see header
+ */
+eap_md5_t *eap_md5_create_peer(identification_t *server, identification_t *peer)
+{
+       private_eap_md5_t *this = eap_md5_create_generic(server, peer);
+       
+       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
+       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer;
+
        return &this->public;
 }
+
similarity index 62%
rename from src/charon/sa/authenticators/eap/eap_md5.h
rename to src/charon/plugins/eap_md5/eap_md5.h
index 260210b599d0781d06a9dfedb757237af828fa79..bcd505c590ae0a9fb42d4ccb0641253590d53a95 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file eap_md5.h
- *
- * @brief Interface of eap_md5_t.
- *
- */
-
 /*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 eap_md5_i eap_md5
+ * @{ @ingroup eap_md5
  */
 
 #ifndef EAP_MD5_H_
@@ -28,13 +28,7 @@ typedef struct eap_md5_t eap_md5_t;
 #include <sa/authenticators/eap/eap_method.h>
 
 /**
- * @brief Implementation of the eap_method_t interface using EAP-MD5 (CHAP).
- *
- * @b Constructors:
- *  - eap_md5_create()
- *  - eap_client_create() using eap_method EAP_MD5
- *
- * @ingroup eap
+ * Implementation of the eap_method_t interface using EAP-MD5 (CHAP).
  */
 struct eap_md5_t {
 
@@ -45,15 +39,21 @@ struct eap_md5_t {
 };
 
 /**
- * @brief Creates the EAP method EAP-MD5.
+ * Creates the EAP method EAP-MD5 acting as server.
  *
  * @param server       ID of the EAP server
  * @param peer         ID of the EAP client
  * @return                     eap_md5_t object
+ */
+eap_md5_t *eap_md5_create_server(identification_t *server, identification_t *peer);
+
+/**
+ * Creates the EAP method EAP-MD5 acting as peer.
  *
- * @ingroup eap
+ * @param server       ID of the EAP server
+ * @param peer         ID of the EAP client
+ * @return                     eap_md5_t object
  */
-eap_md5_t *eap_create(eap_role_t role,
-                                         identification_t *server, identification_t *peer);
+eap_md5_t *eap_md5_create_peer(identification_t *server, identification_t *peer);
 
-#endif /* EAP_MD5_H_ */
+#endif /* EAP_MD5_H_ @}*/
diff --git a/src/charon/plugins/eap_md5/eap_md5_plugin.c b/src/charon/plugins/eap_md5/eap_md5_plugin.c
new file mode 100644 (file)
index 0000000..d00bf71
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "eap_md5_plugin.h"
+
+#include "eap_md5.h"
+
+#include <daemon.h>
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(eap_md5_plugin_t *this)
+{
+       charon->eap->remove_method(charon->eap,
+                                                          (eap_constructor_t)eap_md5_create_server);
+       charon->eap->remove_method(charon->eap,
+                                                          (eap_constructor_t)eap_md5_create_peer);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       eap_md5_plugin_t *this = malloc_thing(eap_md5_plugin_t);
+       
+       this->plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       charon->eap->add_method(charon->eap, EAP_MD5, 0, EAP_SERVER,
+                                                       (eap_constructor_t)eap_md5_create_server);
+       charon->eap->add_method(charon->eap, EAP_MD5, 0, EAP_PEER,
+                                                       (eap_constructor_t)eap_md5_create_peer);
+       
+       return &this->plugin;
+}
+
diff --git a/src/charon/plugins/eap_md5/eap_md5_plugin.h b/src/charon/plugins/eap_md5/eap_md5_plugin.h
new file mode 100644 (file)
index 0000000..8387a20
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup eap_md5 eap_md5
+ * @ingroup cplugins
+ *
+ * @defgroup eap_md5_plugin eap_md5_plugin
+ * @{ @ingroup eap_md5
+ */
+
+#ifndef EAP_MD5_PLUGIN_H_
+#define EAP_MD5_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_md5_plugin_t eap_md5_plugin_t;
+
+/**
+ * EAP-MD5 plugin
+ */
+struct eap_md5_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a eap_md5_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* EAP_MD5_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/eap_sim/Makefile.am b/src/charon/plugins/eap_sim/Makefile.am
new file mode 100644 (file)
index 0000000..549e92a
--- /dev/null
@@ -0,0 +1,13 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DSIM_READER_LIB=\"${simreader}\"
+
+plugin_LTLIBRARIES = libcharon-eapsim.la libeapsim-file.la
+
+libcharon_eapsim_la_SOURCES = eap_sim_plugin.h eap_sim_plugin.c eap_sim.h eap_sim.c
+libcharon_eapsim_la_LDFLAGS = -module
+
+libeapsim_file_la_SOURCES = eap_sim_file.c
+libeapsim_file_la_LDFLAGS = -module
+
similarity index 93%
rename from src/charon/sa/authenticators/eap/eap_sim.c
rename to src/charon/plugins/eap_sim/eap_sim.c
index 90898fb461782f59ad331497af392a07f77eb7ce..70651c91dc7c873736273eac69986cd66439357c 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_sim.c
- *
- * @brief Implementation of eap_sim_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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.h"
@@ -139,6 +134,21 @@ struct private_eap_sim_t {
         */
        identification_t *peer;
        
+       /**
+        * hashing function
+        */
+       hasher_t *hasher;
+       
+       /**
+        * prf
+        */
+       prf_t *prf;
+       
+       /**
+        * MAC function
+        */
+       signer_t *signer;
+       
        /**
         * SIM cardreader function loaded from library
         */
@@ -403,13 +413,11 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier
         * chunk mac_data to "to-sign" chunk */
        if (mac_pos)
        {
-               signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
-               signer->set_key(signer, this->k_auth);
+               this->signer->set_key(this->signer, this->k_auth);
                mac_data = chunk_cata("cc", message, mac_data);
-               signer->get_signature(signer, mac_data, mac_pos);
+               this->signer->get_signature(this->signer, mac_data, mac_pos);
                DBG3(DBG_IKE, "AT_MAC signature of %B\n is %b",
                         &mac_data, mac_pos, MAC_LEN);
-               signer->destroy(signer);
        }
        
        payload = eap_payload_create_data(message);
@@ -520,30 +528,24 @@ static status_t peer_process_start(private_eap_sim_t *this, eap_payload_t *in,
 static void derive_keys(private_eap_sim_t *this, chunk_t kcs)
 {
        chunk_t tmp, mk;
-       hasher_t *hasher;
-       prf_t *prf;
        int i;
 
        /* build MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version) */
        tmp = chunk_cata("ccccc", this->peer->get_encoding(this->peer), kcs,
                                         this->nonce, this->version_list, this->version);
-       hasher = hasher_create(HASH_SHA1);
-       mk = chunk_alloca(hasher->get_hash_size(hasher));
-       hasher->get_hash(hasher, tmp, mk.ptr);
-       hasher->destroy(hasher);
+       mk = chunk_alloca(this->hasher->get_hash_size(this->hasher));
+       this->hasher->get_hash(this->hasher, tmp, mk.ptr);
        DBG3(DBG_IKE, "MK = SHA1(%B\n) = %B", &tmp, &mk);
        
        /* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf()
         * FIPS PRF has 320 bit block size, we need 160 byte for keys
         *  => run prf four times */
-       prf = prf_create(PRF_FIPS_SHA1_160);
-       prf->set_key(prf, mk);
-       tmp = chunk_alloca(prf->get_block_size(prf) * 4);
+       this->prf->set_key(this->prf, mk);
+       tmp = chunk_alloca(this->prf->get_block_size(this->prf) * 4);
        for (i = 0; i < 4; i++)
        {
-               prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * i);
+               this->prf->get_bytes(this->prf, chunk_empty, tmp.ptr + tmp.len / 4 * i);
        }
-       prf->destroy(prf);
        chunk_free(&this->k_encr);
        chunk_free(&this->k_auth);
        chunk_free(&this->msk);
@@ -564,7 +566,6 @@ static status_t peer_process_challenge(private_eap_sim_t *this,
        sim_attribute_t attribute;
        u_int8_t identifier;
        chunk_t mac = chunk_empty, rands = chunk_empty;
-       signer_t *signer;
        
        if (this->tries-- <= 0)
        {
@@ -670,19 +671,16 @@ static status_t peer_process_challenge(private_eap_sim_t *this,
        derive_keys(this, kcs);
        
        /* verify AT_MAC attribute, signature is over "EAP packet | NONCE_MT"  */
-       signer = signer_create(AUTH_HMAC_SHA1_128);
-       signer->set_key(signer, this->k_auth);
+       this->signer->set_key(this->signer, this->k_auth);
        tmp = chunk_cata("cc", in->get_data(in), this->nonce);
-       if (!signer->verify_signature(signer, tmp, mac))
+       if (!this->signer->verify_signature(this->signer, tmp, mac))
        {
                DBG1(DBG_IKE, "AT_MAC verification failed");
-               signer->destroy(signer);
                *out = build_payload(this, identifier, SIM_CLIENT_ERROR,
                                                         AT_CLIENT_ERROR_CODE, client_error_general,
                                                         AT_END);
                return NEED_MORE;
        }
-       signer->destroy(signer);
        
        /* build response, AT_MAC is built over "EAP packet | n*SRES" */
        *out = build_payload(this, identifier, SIM_CHALLENGE,
@@ -700,7 +698,6 @@ static status_t server_process_challenge(private_eap_sim_t *this,
        chunk_t message, data;
        sim_attribute_t attribute;
        chunk_t mac = chunk_empty, tmp;
-       signer_t *signer;
        
        message = in->get_data(in);
        read_header(&message);
@@ -729,16 +726,13 @@ static status_t server_process_challenge(private_eap_sim_t *this,
                return FAILED;
        }
        /* verify AT_MAC attribute, signature is over "EAP packet | n*SRES"  */
-       signer = signer_create(AUTH_HMAC_SHA1_128);
-       signer->set_key(signer, this->k_auth);
+       this->signer->set_key(this->signer, this->k_auth);
        tmp = chunk_cata("cc", in->get_data(in), this->sreses);
-       if (!signer->verify_signature(signer, tmp, mac))
+       if (!this->signer->verify_signature(this->signer, tmp, mac))
        {
                DBG1(DBG_IKE, "AT_MAC verification failed");
-               signer->destroy(signer);
                return FAILED;
        }
-       signer->destroy(signer);
        return SUCCESS;
 }
 
@@ -942,7 +936,7 @@ static status_t peer_process(private_eap_sim_t *this,
  * Implementation of eap_method_t.process for the server
  */
 static status_t server_process(private_eap_sim_t *this,
-                                                        eap_payload_t *in, eap_payload_t **out)
+                                                          eap_payload_t *in, eap_payload_t **out)
 {
        sim_subtype_t type;
        chunk_t message;
@@ -1023,6 +1017,9 @@ static bool is_mutual(private_eap_sim_t *this)
 static void destroy(private_eap_sim_t *this)
 {
        dlclose(this->handle);
+       DESTROY_IF(this->hasher);
+       DESTROY_IF(this->prf);
+       DESTROY_IF(this->signer);
        chunk_free(&this->nonce);
        chunk_free(&this->sreses);
        chunk_free(&this->version_list);
@@ -1033,11 +1030,11 @@ static void destroy(private_eap_sim_t *this)
        free(this);
 }
 
-/*
- * Described in header.
+/**
+ * Generic constructor for both roles
  */
-eap_sim_t *eap_create(eap_role_t role,
-                                         identification_t *server, identification_t *peer)
+eap_sim_t *eap_sim_create_generic(eap_role_t role, identification_t *server,
+                                                                 identification_t *peer)
 {
        private_eap_sim_t *this;
        randomizer_t *randomizer;
@@ -1121,5 +1118,33 @@ eap_sim_t *eap_create(eap_role_t role,
        this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
        this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
        
+       this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+       this->prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
+       this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128);
+       if (!this->hasher || !this->prf || !this->signer)
+       {
+               DBG1(DBG_IKE, "initiating EAP-SIM failed, FIPS-PRF/SHA1 not supported");
+               destroy(this);
+               return NULL;
+       }
        return &this->public;
 }
+
+/*
+ * Described in header.
+ */
+eap_sim_t *eap_sim_create_server(identification_t *server,
+                                                                identification_t *peer)
+{
+       return eap_sim_create_generic(EAP_SERVER, server, peer);
+}
+
+/*
+ * Described in header.
+ */
+eap_sim_t *eap_sim_create_peer(identification_t *server,
+                                                          identification_t *peer)
+{
+       return eap_sim_create_generic(EAP_PEER, server, peer);
+}
+                                                                
similarity index 82%
rename from src/charon/sa/authenticators/eap/eap_sim.h
rename to src/charon/plugins/eap_sim/eap_sim.h
index d50cf73970807c5cd7f6dffca1d3d723437b2327..65020aa644f8462dc1ccbeb6936794642c0bba64 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file eap_sim.h
- *
- * @brief Interface of eap_sim_t.
- *
- */
-
 /*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * for more details.
  */
 
+/**
+ * @defgroup eap_sim_i eap_sim
+ * @{ @ingroup eap_sim
+ */
+
 #ifndef EAP_SIM_H_
 #define EAP_SIM_H_
 
@@ -33,7 +31,7 @@ typedef struct eap_sim_t eap_sim_t;
 #endif /* SIM_READER_LIB */
 
 /** 
- * @brief Cardreaders SIM function.
+ * Cardreaders SIM function.
  *
  * @param rand                 RAND to run algo with
  * @param rand_length  length of value in rand
@@ -53,7 +51,7 @@ typedef int (*sim_algo_t)(const unsigned char *rand, int rand_length,
 #endif /* SIM_READER_ALG */
 
 /** 
- * @brief Function to get a SIM triplet.
+ * Function to get a SIM triplet.
  *
  * @param identity             identity (imsi) to get a triplet for                    
  * @param rand                 buffer to get RAND
@@ -75,7 +73,7 @@ typedef int (*sim_get_triplet_t)(char *identity,
 #endif /* SIM_READER_GET_TRIPLET */
 
 /**
- * @brief Implementation of the eap_method_t interface using EAP-SIM.
+ * Implementation of the eap_method_t interface using EAP-SIM.
  *
  * This EAP-SIM client implementation uses another pluggable library to
  * access the SIM card/triplet provider. This module is specified using the
@@ -83,12 +81,6 @@ typedef int (*sim_get_triplet_t)(char *identity,
  * calculate a triplet (client), and/or a sim_get_triplet() function to get
  * a triplet (server). These functions are named to the SIM_READER_ALG and
  * the SIM_READER_GET_TRIPLET definitions.
- *
- * @b Constructors:
- *  - eap_create() of this module
- *  - eap_client_create() using eap_method EAP_SIM
- *
- * @ingroup eap
  */
 struct eap_sim_t {
 
@@ -99,16 +91,21 @@ struct eap_sim_t {
 };
 
 /**
- * @brief Creates the EAP method EAP-SIM.
+ * Creates the EAP method EAP-SIM acting as server.
  *
- * @param role         role of the module, client/server
  * @param server       ID of the EAP server
  * @param peer         ID of the EAP client
  * @return                     eap_sim_t object
+ */
+eap_sim_t *eap_sim_create_server(identification_t *server, identification_t *peer);
+
+/**
+ * Creates the EAP method EAP-SIM acting as peer.
  *
- * @ingroup eap
+ * @param server       ID of the EAP server
+ * @param peer         ID of the EAP client
+ * @return                     eap_sim_t object
  */
-eap_sim_t *eap_create(eap_role_t role,
-                                         identification_t *server, identification_t *peer);
+eap_sim_t *eap_sim_create_peer(identification_t *server, identification_t *peer);
 
-#endif /* EAP_SIM_H_ */
+#endif /* EAP_SIM_H_ @}*/
similarity index 94%
rename from src/charon/sa/authenticators/eap/sim/eap_sim_file.c
rename to src/charon/plugins/eap_sim/eap_sim_file.c
index 2ab45a5780e2b792a521cff9f841b0b901ae79b4..7040a5acea547ab0270fe2eed6a01801933a38e0 100644 (file)
@@ -1,10 +1,3 @@
-/**\r
- * @file eap_sim.h\r
- *\r
- * @brief Interface of eap_sim_t.\r
- *\r
- */\r
-\r
 /*\r
  * Copyright (C) 2007 Martin Willi\r
  * Hochschule fuer Technik Rapperswil\r
@@ -17,7 +10,9 @@
  * This program is distributed in the hope that it will be useful, but\r
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
- * for more details.\r
+ * for more details.
+ *
+ * $Id$
  */\r
 \r
 #include <string.h>\r
diff --git a/src/charon/plugins/eap_sim/eap_sim_plugin.c b/src/charon/plugins/eap_sim/eap_sim_plugin.c
new file mode 100644 (file)
index 0000000..8fbad42
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "eap_sim_plugin.h"
+
+#include "eap_sim.h"
+
+#include <daemon.h>
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(eap_sim_plugin_t *this)
+{
+       charon->eap->remove_method(charon->eap,
+                                                          (eap_constructor_t)eap_sim_create_server);
+       charon->eap->remove_method(charon->eap,
+                                                          (eap_constructor_t)eap_sim_create_peer);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       eap_sim_plugin_t *this = malloc_thing(eap_sim_plugin_t);
+       
+       this->plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_SERVER,
+                                                       (eap_constructor_t)eap_sim_create_server);
+       charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_PEER,
+                                                       (eap_constructor_t)eap_sim_create_peer);
+       
+       return &this->plugin;
+}
+
diff --git a/src/charon/plugins/eap_sim/eap_sim_plugin.h b/src/charon/plugins/eap_sim/eap_sim_plugin.h
new file mode 100644 (file)
index 0000000..e142b89
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup eap_sim eap_sim
+ * @ingroup cplugins
+ *
+ * @defgroup eap_sim_plugin eap_sim_plugin
+ * @{ @ingroup eap_sim
+ */
+
+#ifndef EAP_SIM_PLUGIN_H_
+#define EAP_SIM_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_sim_plugin_t eap_sim_plugin_t;
+
+/**
+ * EAP-sim plugin
+ */
+struct eap_sim_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a eap_sim_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* EAP_SIM_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/med_db/Makefile.am b/src/charon/plugins/med_db/Makefile.am
new file mode 100644 (file)
index 0000000..f7608da
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libcharon-med-db.la
+libcharon_med_db_la_SOURCES = med_db_plugin.h med_db_plugin.c \
+                             med_db_creds.h med_db_creds.c
+libcharon_med_db_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/med_db/med_db_creds.c b/src/charon/plugins/med_db/med_db_creds.c
new file mode 100644 (file)
index 0000000..f8aed25
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "med_db_creds.h"
+
+#include <daemon.h>
+#include <library.h>
+#include <utils/enumerator.h>
+
+typedef struct private_med_db_creds_t private_med_db_creds_t;
+
+/**
+ * Private data of an med_db_creds_t object
+ */
+struct private_med_db_creds_t {
+
+       /**
+        * Public part
+        */
+       med_db_creds_t public;
+       
+       /**
+        * underlying database handle
+        */
+       database_t *db;
+};
+
+/**
+ * data passed between enumerate calls
+ */
+typedef struct  {
+       /** current shared key */
+       shared_key_t *current;
+} data_t;
+
+typedef struct private_shared_key_t private_shared_key_t;
+/**
+ * shared key implementation
+ */
+struct private_shared_key_t {
+       /** implements shared_key_t*/
+       shared_key_t public;
+       /** data of the key */
+       chunk_t key;
+       /** reference counter */
+       refcount_t ref;
+};
+
+/**
+ * Destroy allocated data_t struct
+ */
+static void data_destroy(data_t *this)
+{
+       DESTROY_IF(this->current);
+       free(this);
+}
+
+/**
+ * Implementation of shared_key_t.get_type.
+ */
+static shared_key_type_t get_type(private_shared_key_t *this)
+{
+       return SHARED_IKE;
+}
+
+/**
+ * Implementation of shared_key_t.get_ref.
+ */
+static private_shared_key_t* get_ref(private_shared_key_t *this)
+{
+       ref_get(&this->ref);
+       return this;
+}
+
+/**
+ * Implementation of shared_key_t.destroy
+ */
+static void shared_key_destroy(private_shared_key_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               chunk_free(&this->key);
+               free(this);
+       }
+}
+
+/**
+ * Implementation of shared_key_t.get_key.
+ */
+static chunk_t get_key(private_shared_key_t *this)
+{
+       return this->key;
+}
+
+/**
+ * create a shared key
+ */
+static shared_key_t *shared_key_create(chunk_t key)
+{
+       private_shared_key_t *this = malloc_thing(private_shared_key_t);
+
+       this->public.get_type = (shared_key_type_t(*)(shared_key_t*))get_type;
+       this->public.get_key = (chunk_t(*)(shared_key_t*))get_key;
+       this->public.get_ref = (shared_key_t*(*)(shared_key_t*))get_ref;
+       this->public.destroy = (void(*)(shared_key_t*))shared_key_destroy;
+
+       this->key = chunk_clone(key);
+       this->ref = 1;
+       return &this->public;
+}
+
+/**
+ * filter for enumerator, returns for each SQL result a shared key and match
+ */
+static bool filter(data_t *this, chunk_t *chunk, shared_key_t **out,
+                                  void **unused1, id_match_t *match_me,
+                                  void **unused2, id_match_t *match_other)
+{
+       DESTROY_IF(this->current);
+       this->current = shared_key_create(*chunk);
+       *out = this->current;
+       /* we have unique matches only, but do not compare own ID */
+       if (match_me)
+       {
+               *match_me = ID_MATCH_ANY;
+       }
+       if (match_other)
+       {
+               *match_other = ID_MATCH_PERFECT;
+       }
+       return TRUE;
+}
+
+
+/**
+ * Implements credential_set_t.create_shared_enumerator
+ */
+static enumerator_t* create_shared_enumerator(private_med_db_creds_t *this, 
+                                                       shared_key_type_t type, identification_t *me,
+                                                       identification_t *other)
+{
+       enumerator_t *enumerator;
+       data_t *data;
+       
+       if (type != SHARED_IKE)
+       {
+               return NULL;
+       }
+       enumerator = this->db->query(this->db,
+                                                                "SELECT Psk FROM Peer WHERE PeerId = ?",
+                                                                DB_BLOB, other->get_encoding(other),
+                                                                DB_BLOB);
+       if (enumerator)
+       {
+               data = malloc_thing(data_t);
+               data->current = NULL;
+               return enumerator_create_filter(enumerator,     (void*)filter,
+                                                                               data, (void*)data_destroy);
+       }
+       return NULL;
+}
+
+/**
+ * returns null
+ */
+static void *return_null()
+{
+       return NULL;
+}
+       
+/**
+ * Implementation of backend_t.destroy.
+ */
+static void destroy(private_med_db_creds_t *this)
+{
+    free(this);
+}
+
+/**
+ * Described in header.
+ */
+med_db_creds_t *med_db_creds_create(database_t *db)
+{
+       private_med_db_creds_t *this = malloc_thing(private_med_db_creds_t);
+
+       this->public.set.create_private_enumerator = (void*)return_null;
+       this->public.set.create_cert_enumerator = (void*)return_null;
+       this->public.set.create_shared_enumerator = (void*)create_shared_enumerator;
+       this->public.set.create_cdp_enumerator = (void*)return_null;
+
+       this->public.destroy = (void (*)(med_db_creds_t*))destroy;
+       
+       this->db = db;
+       
+       return &this->public;
+}
+
diff --git a/src/charon/plugins/med_db/med_db_creds.h b/src/charon/plugins/med_db/med_db_creds.h
new file mode 100644 (file)
index 0000000..1665b87
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007-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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup med_db_creds_i med_db_creds
+ * @{ @ingroup med_db_creds
+ */
+
+#ifndef MED_DB_CREDS_H_
+#define MED_DB_CREDS_H_
+
+#include <credentials/credential_set.h>
+#include <database/database.h>
+
+typedef struct med_db_creds_t med_db_creds_t;
+
+/**
+ * Mediation credentials database.
+ */
+struct med_db_creds_t {
+
+       /**
+        * Implements credential_set_t interface
+        */
+       credential_set_t set;
+       
+       /**
+        * Destroy the credentials databse.
+        */
+       void (*destroy)(med_db_creds_t *this);  
+};
+
+/**
+ * Create the med_db credentials db.
+ *
+ * @param database             underlying database
+ * @return                             credential set implementation on that database
+ */
+med_db_creds_t *med_db_creds_create(database_t *database);
+
+#endif /* MED_DB_CREDS_H_ @}*/
diff --git a/src/charon/plugins/med_db/med_db_plugin.c b/src/charon/plugins/med_db/med_db_plugin.c
new file mode 100644 (file)
index 0000000..033ec91
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "med_db_plugin.h"
+
+#include "med_db_creds.h"
+
+#include <daemon.h>
+
+typedef struct private_med_db_plugin_t private_med_db_plugin_t;
+
+/**
+ * private data of med_db plugin
+ */
+struct private_med_db_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       med_db_plugin_t public;
+       
+       /**
+        * database connection instance
+        */
+       database_t *db;
+       
+       /**
+        * med_db credential set instance
+        */
+       med_db_creds_t *creds;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_med_db_plugin_t *this)
+{
+       charon->credentials->remove_set(charon->credentials, &this->creds->set);
+       this->creds->destroy(this->creds);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       char *uri;
+       private_med_db_plugin_t *this = malloc_thing(private_med_db_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       uri = lib->settings->get_str(lib->settings, "plugins.med_db.database", NULL);
+       if (!uri)
+       {
+               DBG1(DBG_CFG, "mediation database URI not defined, skipped");
+               free(this);
+               return NULL;
+       }
+       
+       if (this->db == NULL)
+       {
+               DBG1(DBG_CFG, "opening mediation server database failed");
+               free(this);
+               return NULL;
+       }
+       
+       this->creds = med_db_creds_create(this->db);
+       
+       charon->credentials->add_set(charon->credentials, &this->creds->set);
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/med_db/med_db_plugin.h b/src/charon/plugins/med_db/med_db_plugin.h
new file mode 100644 (file)
index 0000000..42d55ad
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup med_db med_db
+ * @ingroup cplugins
+ *
+ * @defgroup med_db_plugin med_db_plugin
+ * @{ @ingroup med_db
+ */
+
+#ifndef MED_DB_PLUGIN_H_
+#define MED_DB_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct med_db_plugin_t med_db_plugin_t;
+
+/**
+ * Mediation server database plugin.
+ */
+struct med_db_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a med_db_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* MED_DB_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/sql/Makefile.am b/src/charon/plugins/sql/Makefile.am
new file mode 100644 (file)
index 0000000..813c601
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libcharon-sql.la
+libcharon_sql_la_SOURCES = sql_plugin.h sql_plugin.c \
+  sql_config.h sql_config.c
+libcharon_sql_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/sql/config.sql b/src/charon/plugins/sql/config.sql
new file mode 100644 (file)
index 0000000..64aaea7
--- /dev/null
@@ -0,0 +1,73 @@
+
+DROP TABLE IF EXISTS ike_configs;
+CREATE TABLE ike_configs (
+       id INTEGER PRIMARY KEY AUTOINCREMENT,
+       certreq INTEGER,
+       force_encap INTEGER,
+       local TEXT, 
+       remote TEXT
+);
+
+DROP TABLE IF EXISTS child_configs;
+CREATE TABLE child_configs (
+       id INTEGER PRIMARY KEY AUTOINCREMENT,
+       name TEXT,
+       lifetime INTEGER,
+       rekeytime INTEGER,
+       jitter INTEGER,
+       updown TEXT,
+       hostaccess INTEGER,
+       mode INTEGER
+);
+
+DROP TABLE IF EXISTS peer_config_child_config;
+CREATE TABLE peer_config_child_config (
+       peer_cfg INTEGER,
+       child_cfg INTEGER
+);
+
+DROP TABLE IF EXISTS traffic_selectors;
+CREATE TABLE traffic_selectors (
+       id INTEGER PRIMARY KEY AUTOINCREMENT,
+       type INTEGER,
+       protocol INTEGER,
+       start_addr TEXT,
+       end_addr TEXT,
+       start_port INTEGER,
+       end_port INTEGER
+);
+
+DROP TABLE IF EXISTS child_config_traffic_selector;
+CREATE TABLE child_config_traffic_selector (
+       child_cfg INTEGER,
+       traffic_selector INTEGER,
+       kind INTEGER
+);
+
+DROP TABLE IF EXISTS peer_configs;
+CREATE TABLE peer_configs (
+       id INTEGER PRIMARY KEY AUTOINCREMENT,
+       name TEXT,
+       ike_version INTEGER,
+       ike_cfg INTEGER,
+       local_id TEXT,
+       remote_id TEXT,
+       cert_policy INTEGER,
+       auth_method INTEGER,
+       eap_type INTEGER,
+       eap_vendor INTEGER,
+       keyingtries INTEGER, 
+       rekeytime INTEGER, 
+       reauthtime INTEGER, 
+       jitter INTEGER, 
+       overtime INTEGER,
+       mobike INTEGER,
+       dpd_delay INTEGER, 
+       dpd_action INTEGER,
+       local_vip TEXT,
+       remote_vip TEXT,
+       mediation INTEGER,
+       mediated_by INTEGER,
+       peer_id TEXT
+);
+
diff --git a/src/charon/plugins/sql/cred.sql b/src/charon/plugins/sql/cred.sql
new file mode 100644 (file)
index 0000000..4b53e4e
--- /dev/null
@@ -0,0 +1,24 @@
+
+DROP TABLE IF EXISTS shared_secrets;
+CREATE TABLE shared_secrets (
+       id INTEGER PRIMARY KEY AUTOINCREMENT,
+       type INTEGER,
+       local TEXT, 
+       remote TEXT
+);
+
+DROP TABLE IF EXISTS certificates;
+CREATE TABLE certificates (
+       id INTEGER PRIMARY KEY AUTOINCREMENT,
+       type INTEGER,
+       subject TEXT,
+       data BLOB,
+);
+
+DROP TABLE IF EXISTS private_keys;
+CREATE TABLE private_keys (
+       id INTEGER PRIMARY KEY AUTOINCREMENT,
+       type INTEGER,
+       keyid BLOB,
+       data BLOB,
+);
diff --git a/src/charon/plugins/sql/sql_config.c b/src/charon/plugins/sql/sql_config.c
new file mode 100644 (file)
index 0000000..eaa9da5
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2006-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.
+ *
+ * $Id$
+ */
+
+#include <string.h>
+
+#include "sql_config.h"
+
+#include <daemon.h>
+
+typedef struct private_sql_config_t private_sql_config_t;
+
+/**
+ * Private data of an sql_config_t object
+ */
+struct private_sql_config_t {
+
+       /**
+        * Public part
+        */
+       sql_config_t public;
+       
+       /**
+        * database connection
+        */
+       database_t *db;
+};
+
+/**
+ * forward declaration
+ */
+static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
+                                                                 identification_t *me, identification_t *other);
+
+/**
+ * build a traffic selector from a SQL query
+ */
+static traffic_selector_t *build_traffic_selector(private_sql_config_t *this,
+                                                                                                 enumerator_t *e, bool *local)
+{
+       int type, protocol, start_port, end_port;
+       char *start_addr, *end_addr;
+       traffic_selector_t *ts;
+       enum {
+               TS_LOCAL = 0,
+               TS_REMOTE = 1,
+               TS_LOCAL_DYNAMIC = 2,
+               TS_REMOTE_DYNAMIC = 3,
+       } kind;
+       
+       while (e->enumerate(e, &kind, &type, &protocol,
+                                               &start_addr, &end_addr, &start_port, &end_port))
+       {
+               *local = FALSE;
+               switch (kind)
+               {
+                       case TS_LOCAL:
+                               *local = TRUE;
+                               /* FALL */
+                       case TS_REMOTE:
+                               ts = traffic_selector_create_from_string(protocol, type, 
+                                                               start_addr, start_port, end_addr, end_port);
+                               break;
+                       case TS_LOCAL_DYNAMIC:
+                               *local = TRUE;
+                               /* FALL */
+                       case TS_REMOTE_DYNAMIC:
+                               ts = traffic_selector_create_dynamic(protocol, type,
+                                                               start_port, end_port);
+                               break;
+                       default:
+                               continue;
+               }
+               if (ts)
+               {
+                       return ts;
+               }
+       }
+       return NULL;
+}
+
+/**
+ * Add traffic selectors to a child config
+ */
+static void add_traffic_selectors(private_sql_config_t *this,
+                                                                 child_cfg_t *child, int id)
+{
+       enumerator_t *e;
+       traffic_selector_t *ts;
+       bool local;
+       
+       e = this->db->query(this->db,
+                       "SELECT kind, type, protocol, "
+                       "start_addr, end_addr, start_port, end_port "
+                       "FROM traffic_selectors JOIN child_config_traffic_selector "
+                       "ON id = traffic_selector WHERE child_cfg = ?",
+                       DB_INT, id,
+                       DB_INT, DB_INT, DB_INT,
+                       DB_TEXT, DB_TEXT, DB_INT, DB_INT);
+       if (e)
+       {
+               while ((ts = build_traffic_selector(this, e, &local)))
+               {
+                       child->add_traffic_selector(child, local, ts);
+               }
+               e->destroy(e);
+       }
+}
+
+/**
+ * build a Child configuration from a SQL query
+ */
+static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
+{
+       int id, lifetime, rekeytime, jitter, hostaccess, mode;
+       char *name, *updown;
+       child_cfg_t *child_cfg;
+       
+       if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter, 
+                                               &updown, &hostaccess, &mode))
+       {
+               child_cfg = child_cfg_create(name, lifetime, rekeytime, jitter,
+                                                                        updown, hostaccess, mode);
+               /* TODO: read proposal from db */
+               child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+               add_traffic_selectors(this, child_cfg, id);
+               return child_cfg;
+       }
+       return NULL;
+}
+
+/**
+ * Add child configs to peer config
+ */
+static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
+{
+       enumerator_t *e;
+       child_cfg_t *child_cfg;
+       
+       e = this->db->query(this->db,
+                       "SELECT id, name, lifetime, rekeytime, jitter, "
+                       "updown, hostaccess, mode "
+                       "FROM child_configs JOIN peer_config_child_config ON id = child_cfg "
+                       "WHERE peer_cfg = ?",
+                       DB_INT, id,
+                       DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT,
+                       DB_TEXT, DB_INT, DB_INT);
+       if (e)
+       {
+               while ((child_cfg = build_child_cfg(this, e)))
+               {
+                       peer->add_child_cfg(peer, child_cfg);
+               }
+               e->destroy(e);
+       }
+}
+
+/**
+ * build a ike configuration from a SQL query
+ */
+static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
+                                                               host_t *my_host, host_t *other_host)
+{
+       int certreq, force_encap;
+       char *local, *remote;
+       
+       while (e->enumerate(e, &certreq, &force_encap, &local, &remote))
+       {
+               host_t *me, *other;
+               ike_cfg_t *ike_cfg;
+               
+               me = host_create_from_string(local, 500);
+               if (!me)
+               {
+                       continue;
+               }
+               if (my_host && !me->is_anyaddr(me) &&
+                       !me->ip_equals(me, my_host))
+               {
+                       me->destroy(me);
+                       continue;
+               }
+               other = host_create_from_string(remote, 500);
+               if (!other)
+               {
+                       me->destroy(me);
+                       continue;
+               }
+               if (other_host && !other->is_anyaddr(other) &&
+                       !other->ip_equals(other, other_host))
+               {
+                       me->destroy(me);
+                       other->destroy(other);
+                       continue;
+               }
+               ike_cfg = ike_cfg_create(certreq, force_encap, me, other);
+               /* TODO: read proposal from db */
+               ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+               return ike_cfg;
+       }
+       return NULL;
+}
+
+/**
+ * Query a IKE config by its id
+ */
+static ike_cfg_t* get_ike_cfg_by_id(private_sql_config_t *this, int id)
+{
+       enumerator_t *e;
+       ike_cfg_t *ike_cfg = NULL;
+       
+       e = this->db->query(this->db,
+                       "SELECT certreq, force_encap, local, remote "
+                       "FROM ike_configs WHERE id = ?",
+                       DB_INT, id,
+                       DB_INT, DB_INT, DB_TEXT, DB_TEXT);
+       if (e)
+       {
+               ike_cfg = build_ike_cfg(this, e, NULL, NULL);
+               e->destroy(e);
+       }
+       return ike_cfg;
+}
+
+/**
+ * Query a peer config by its id
+ */
+static peer_cfg_t *get_peer_cfg_by_id(private_sql_config_t *this, int id)
+{
+       enumerator_t *e;
+       peer_cfg_t *peer_cfg = NULL;
+       
+       e = this->db->query(this->db,
+                       "SELECT id, name, ike_cfg, local_id, remote_id, cert_policy, "
+                       "auth_method, eap_type, eap_vendor, keyingtries, "
+                       "rekeytime, reauthtime, jitter, overtime, mobike, "
+                       "dpd_delay, dpd_action, local_vip, remote_vip, "
+                       "mediation, mediated_by, peer_id "
+                       "FROM peer_configs WHERE id = ?",
+                       DB_INT, id,
+                       DB_INT, DB_INT, DB_TEXT, DB_TEXT, DB_INT,
+                       DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_INT, DB_TEXT, DB_TEXT,
+                       DB_INT, DB_INT, DB_TEXT);
+       if (e)
+       {
+               peer_cfg = build_peer_cfg(this, e, NULL, NULL);
+               e->destroy(e);
+       }
+       return peer_cfg;
+}
+
+/**
+ * build a peer configuration from a SQL query
+ */
+static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
+                                                                 identification_t *me, identification_t *other)
+{
+       int id, ike_cfg, cert_policy, auth_method, eap_type, eap_vendor,
+               keyingtries, rekeytime, reauthtime, jitter, overtime, mobike,
+               dpd_delay, dpd_action, mediation, mediated_by;
+       char *local_id, *remote_id, *local_vip, *remote_vip, *peer_id, *name;
+       
+       while (e->enumerate(e, &id, &name, &ike_cfg, &local_id, &remote_id, &cert_policy, 
+                                               &auth_method, &eap_type, &eap_vendor, &keyingtries, 
+                                               &rekeytime, &reauthtime, &jitter, &overtime, &mobike, 
+                                               &dpd_delay, &dpd_action, &local_vip, &remote_vip, 
+                                               &mediation, &mediated_by, &peer_id))
+       {
+               ike_cfg_t *ike;
+               peer_cfg_t *peer_cfg, *mediated_cfg;
+               identification_t *my_id, *other_id, *peer;
+               host_t *my_vip, *other_vip;
+               
+               my_id = identification_create_from_string(local_id);
+               if (!my_id)
+               {
+                       continue;
+               }
+               if (me && !me->matches(me, my_id))
+               {
+                       my_id->destroy(my_id);
+                       continue;
+               }
+               other_id = identification_create_from_string(remote_id);
+               if (!other_id)
+               {
+                       my_id->destroy(my_id);
+                       continue;
+               }
+               if (other && !other->matches(other, other_id))
+               {
+                       other_id->destroy(other_id);
+                       my_id->destroy(my_id);
+                       continue;
+               }
+               ike = get_ike_cfg_by_id(this, ike_cfg);
+               mediated_cfg = mediated_by ? get_peer_cfg_by_id(this, mediated_by) : NULL;
+               peer = peer_id ? identification_create_from_string(peer_id) : NULL;
+               my_vip = local_vip ? host_create_from_string(local_vip, 0) : NULL;
+               other_vip = remote_vip ? host_create_from_string(remote_vip, 0) : NULL;
+               
+               if (ike)
+               {
+                       peer_cfg = peer_cfg_create(
+                                                               name, 2, ike, my_id, other_id, cert_policy,
+                                                               auth_method, eap_type, eap_vendor, keyingtries, 
+                                                               rekeytime, reauthtime, jitter, overtime, mobike,
+                                                               dpd_delay, dpd_action, my_vip, other_vip,
+                                                               mediation, mediated_cfg, peer);
+                       add_child_cfgs(this, peer_cfg, id);
+                       return peer_cfg;
+               }
+               DESTROY_IF(ike);
+               DESTROY_IF(mediated_cfg);
+               DESTROY_IF(peer);
+               DESTROY_IF(my_vip);
+               DESTROY_IF(other_vip);
+               DESTROY_IF(my_id);
+               DESTROY_IF(other_id);
+       }
+       return NULL;
+}
+
+/**
+ * implements backend_t.get_peer_cfg_by_name.
+ */
+static peer_cfg_t *get_peer_cfg_by_name(private_sql_config_t *this, char *name)
+{
+       enumerator_t *e;
+       peer_cfg_t *peer_cfg = NULL;
+       
+       e = this->db->query(this->db,
+                       "SELECT id, name, ike_cfg, local_id, remote_id, cert_policy, "
+                       "auth_method, eap_type, eap_vendor, keyingtries, "
+                       "rekeytime, reauthtime, jitter, overtime, mobike, "
+                       "dpd_delay, dpd_action, local_vip, remote_vip, "
+                       "mediation, mediated_by, peer_id "
+                       "FROM peer_configs WHERE ike_version = ? AND name = ?",
+                       DB_INT, 2, DB_TEXT, name,
+                       DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_TEXT, DB_INT,
+                       DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_INT, DB_TEXT, DB_TEXT,
+                       DB_INT, DB_INT, DB_TEXT);
+       if (e)
+       {
+               peer_cfg = build_peer_cfg(this, e, NULL, NULL);
+               e->destroy(e);
+       }
+       return peer_cfg;
+}
+
+typedef struct {
+       /** implements enumerator */
+       enumerator_t public;
+       /** reference to context */
+       private_sql_config_t *this;
+       /** filtering own host */
+       host_t *me;
+       /** filtering remote host */
+       host_t *other;
+       /** inner SQL enumerator */
+       enumerator_t *inner;
+       /** currently enumerated peer config */
+       ike_cfg_t *current;
+} ike_enumerator_t;
+
+/**
+ * Implementation of ike_enumerator_t.public.enumerate
+ */
+static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg)
+{
+       DESTROY_IF(this->current);
+       this->current = build_ike_cfg(this->this, this->inner, this->me, this->other);
+       if (this->current)
+       {
+               *cfg = this->current;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * Implementation of ike_enumerator_t.public.destroy
+ */
+static void ike_enumerator_destroy(ike_enumerator_t *this)
+{
+       DESTROY_IF(this->current);
+       this->inner->destroy(this->inner);
+       free(this);
+}
+
+/**
+ * Implementation of backend_t.create_ike_cfg_enumerator.
+ */
+static enumerator_t* create_ike_cfg_enumerator(private_sql_config_t *this,
+                                                                                          host_t *me, host_t *other)
+{
+       ike_enumerator_t *e = malloc_thing(ike_enumerator_t);
+       
+       e->this = this;
+       e->me = me;
+       e->other = other;
+       e->current = NULL;
+       e->public.enumerate = (void*)ike_enumerator_enumerate;
+       e->public.destroy = (void*)ike_enumerator_destroy;
+       
+       e->inner = this->db->query(this->db,
+                       "SELECT certreq, force_encap, local, remote "
+                       "FROM ike_configs",
+                       DB_INT, DB_INT, DB_TEXT, DB_TEXT);
+       if (!e->inner)
+       {
+               free(e);
+               return NULL;
+       }
+       return &e->public;
+}
+
+
+typedef struct {
+       /** implements enumerator */
+       enumerator_t public;
+       /** reference to context */
+       private_sql_config_t *this;
+       /** filtering own identity */
+       identification_t *me;
+       /** filtering remote identity */
+       identification_t *other;
+       /** inner SQL enumerator */
+       enumerator_t *inner;
+       /** currently enumerated peer config */
+       peer_cfg_t *current;
+} peer_enumerator_t;
+
+/**
+ * Implementation of peer_enumerator_t.public.enumerate
+ */
+static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
+{
+       DESTROY_IF(this->current);
+       this->current = build_peer_cfg(this->this, this->inner, this->me, this->other);
+       if (this->current)
+       {
+               *cfg = this->current;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * Implementation of peer_enumerator_t.public.destroy
+ */
+static void peer_enumerator_destroy(peer_enumerator_t *this)
+{
+       DESTROY_IF(this->current);
+       this->inner->destroy(this->inner);
+       free(this);
+}
+
+/**
+ * Implementation of backend_t.create_peer_cfg_enumerator.
+ */
+static enumerator_t* create_peer_cfg_enumerator(private_sql_config_t *this,
+                                                                                               identification_t *me,
+                                                                                               identification_t *other)
+{
+       peer_enumerator_t *e = malloc_thing(peer_enumerator_t);
+       
+       e->this = this;
+       e->me = me;
+       e->other = other;
+       e->current = NULL;
+       e->public.enumerate = (void*)peer_enumerator_enumerate;
+       e->public.destroy = (void*)peer_enumerator_destroy;
+
+       /* TODO: only get configs whose IDs match exactly or contain wildcards */
+       e->inner = this->db->query(this->db,
+                       "SELECT id, name, ike_cfg, local_id, remote_id, cert_policy, "
+                       "auth_method, eap_type, eap_vendor, keyingtries, "
+                       "rekeytime, reauthtime, jitter, overtime, mobike, "
+                       "dpd_delay, dpd_action, local_vip, remote_vip, "
+                       "mediation, mediated_by, peer_id "
+                       "FROM peer_configs WHERE ike_version = ? ",
+                       DB_INT, 2,
+                       DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_TEXT, DB_INT,
+                       DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_INT, DB_TEXT, DB_TEXT,
+                       DB_INT, DB_INT, DB_TEXT);
+       if (!e->inner)
+       {
+               free(e);
+               return NULL;
+       }
+       return &e->public;
+}
+
+/**
+ * Implementation of sql_config_t.destroy.
+ */
+static void destroy(private_sql_config_t *this)
+{
+       free(this);
+}
+
+/**
+ * Described in header.
+ */
+sql_config_t *sql_config_create(database_t *db)
+{
+       private_sql_config_t *this = malloc_thing(private_sql_config_t);
+
+       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;
+       this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
+       this->public.destroy = (void(*)(sql_config_t*))destroy;
+       
+       this->db = db;
+       
+       return &this->public;
+}
+
similarity index 54%
rename from src/charon/config/backends/sqlite_backend.h
rename to src/charon/plugins/sql/sql_config.h
index 4bc1465838245bbd9efd22bce42a1cbe46934a10..829d80da84bbba7b8bd93aacd304b2f2c4149c2c 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file sqlite_backend.h
- *
- * @brief Interface of sqlite_backend_t.
- *
- */
-
 /*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 sql_config_i sql_config
+ * @{ @ingroup sql_config
  */
-#ifndef SQLITE_BACKEND_H_
-#define SQLITE_BACKEND_H_
 
-typedef struct sqlite_backend_t sqlite_backend_t;
+#ifndef SQL_CONFIG_H_
+#define SQL_CONFIG_H_
 
-#include <library.h>
+#include <config/backend.h>
+#include <database/database.h>
 
-#include "backend.h"
+typedef struct sql_config_t sql_config_t;
 
 /**
- * @brief An SQLite based configuration backend.
- *
- * @b Constructors:
- *  - sqlite_backend_create()
- * 
- * @ingroup backends
+ * SQL database configuration backend.
  */
-struct sqlite_backend_t {
-       
+struct sql_config_t {
+
        /**
         * Implements backend_t interface
         */
        backend_t backend;
+       
+       /**
+        * Destry the backend.
+        */
+       void (*destroy)(sql_config_t *this);    
 };
 
 /**
- * @brief Create a backend_t instance implemented as sqlite backend.
+ * Create a sql_config backend instance.
  *
- * @return backend instance
- * 
- * @ingroup backends
+ * @param db           underlying database
+ * @return                     backend instance
  */
-backend_t *backend_create(void);
-
-#endif /* SQLITE_BACKEND_H_ */
+sql_config_t *sql_config_create(database_t *db);
 
+#endif /* SQL_CONFIG_H_ @}*/
diff --git a/src/charon/plugins/sql/sql_plugin.c b/src/charon/plugins/sql/sql_plugin.c
new file mode 100644 (file)
index 0000000..8ee6400
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "sql_plugin.h"
+
+#include <daemon.h>
+#include "sql_config.h"
+
+typedef struct private_sql_plugin_t private_sql_plugin_t;
+
+/**
+ * private data of sql plugin
+ */
+struct private_sql_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       sql_plugin_t public;
+       
+       /**
+        * database connection instance
+        */
+       database_t *db;
+       
+       /**
+        * configuration backend
+        */
+       sql_config_t *config;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_sql_plugin_t *this)
+{
+       charon->backends->remove_backend(charon->backends, &this->config->backend);
+       this->config->destroy(this->config);
+       this->db->destroy(this->db);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       char *uri;
+       private_sql_plugin_t *this;
+       
+       uri = lib->settings->get_str(lib->settings, "charon.plugins.sql.database", NULL);
+       if (!uri)
+       {
+               DBG1(DBG_CFG, "SQL plugin database URI not set");
+               return NULL;
+       }
+       
+       this = malloc_thing(private_sql_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       this->db = lib->db->create(lib->db, uri);
+       if (!this->db)
+       {
+               DBG1(DBG_CFG, "SQL plugin failed to connect to database");
+               free(this);
+               return NULL;
+       }
+       this->config = sql_config_create(this->db);
+               
+       charon->backends->add_backend(charon->backends, &this->config->backend);
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/sql/sql_plugin.h b/src/charon/plugins/sql/sql_plugin.h
new file mode 100644 (file)
index 0000000..978df37
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup sql sql
+ * @ingroup cplugins
+ *
+ * @defgroup sql_plugin sql_plugin
+ * @{ @ingroup sql
+ */
+
+#ifndef SQL_PLUGIN_H_
+#define SQL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sql_plugin_t sql_plugin_t;
+
+/**
+ * SQL database configuration plugin
+ */
+struct sql_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a sql_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SQL_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/sql/test.sql b/src/charon/plugins/sql/test.sql
new file mode 100644 (file)
index 0000000..ec5b401
--- /dev/null
@@ -0,0 +1,47 @@
+
+INSERT INTO ike_configs (
+       certreq, force_encap, local, remote
+) VALUES (
+       0, 0, '0.0.0.0', '152.96.52.150'
+);
+
+INSERT INTO child_configs (
+       name, lifetime, rekeytime, jitter, updown, hostaccess, mode
+) VALUES (
+       'sqltest', 500, 400, 50, NULL, 1, 1
+);
+
+INSERT INTO peer_config_child_config (
+       peer_cfg, child_cfg
+) VALUES (
+       1, 1
+);
+
+INSERT INTO traffic_selectors (
+       type, protocol
+) values (
+       7, 0
+);
+
+INSERT INTO child_config_traffic_selector (
+       child_cfg, traffic_selector, kind
+) VALUES (
+       1, 1, 2
+);
+
+INSERT INTO child_config_traffic_selector (
+       child_cfg, traffic_selector, kind
+) VALUES (
+       1, 1, 3
+);
+
+INSERT INTO peer_configs (
+       name, ike_version, ike_cfg, local_id, remote_id, cert_policy, auth_method, 
+       eap_type, eap_vendor, keyingtries, rekeytime, reauthtime, jitter, overtime, 
+       mobike, dpd_delay, dpd_action, local_vip, remote_vip, 
+       mediation, mediated_by, peer_id
+) VALUES (
+       'sqltest', 2, 1, 'C=CH, O=Linux strongSwan, CN=martin', 'sidv0150.hsr.ch', 0, 0, 
+       0, 0, 0, 500, 2000, 20, 20,
+       1, 120, 0, NULL, NULL, 0, 0, NULL
+);
diff --git a/src/charon/plugins/stroke/Makefile.am b/src/charon/plugins/stroke/Makefile.am
new file mode 100644 (file)
index 0000000..b2aeec1
--- /dev/null
@@ -0,0 +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}\"
+
+plugin_LTLIBRARIES = libcharon-stroke.la
+
+libcharon_stroke_la_SOURCES = stroke.h stroke.c
+libcharon_stroke_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/stroke/stroke.c b/src/charon/plugins/stroke/stroke.c
new file mode 100755 (executable)
index 0000000..9d11284
--- /dev/null
@@ -0,0 +1,3335 @@
+/*
+ * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2006-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$
+ */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+
+#include "stroke.h"
+
+/* stroke message format definition */
+#include <stroke_msg.h>
+
+#include <library.h>
+#include <daemon.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+#include <credentials/certificates/ocsp_request.h>
+#include <credentials/certificates/ocsp_response.h>
+#include <control/controller.h>
+#include <utils/lexparser.h>
+#include <asn1/ttodata.h>
+#include <asn1/pem.h>
+#include <utils/mutex.h>
+#include <processing/jobs/callback_job.h>
+#include <credentials/credential_set.h>
+
+/* configuration directories and files */
+#define CONFIG_DIR IPSEC_CONFDIR
+#define IPSEC_D_DIR CONFIG_DIR "/ipsec.d"
+#define PRIVATE_KEY_DIR IPSEC_D_DIR "/private"
+#define CERTIFICATE_DIR IPSEC_D_DIR "/certs"
+#define CA_CERTIFICATE_DIR IPSEC_D_DIR "/cacerts"
+#define AA_CERTIFICATE_DIR IPSEC_D_DIR "/aacerts"
+#define ATTR_CERTIFICATE_DIR IPSEC_D_DIR "/acerts"
+#define OCSP_CERTIFICATE_DIR IPSEC_D_DIR "/ocspcerts"
+#define CRL_DIR IPSEC_D_DIR "/crls"
+#define SECRETS_FILE CONFIG_DIR "/ipsec.secrets"
+
+/* warning intervals for list functions */
+#define CERT_WARNING_INTERVAL  30      /* days */
+#define CRL_WARNING_INTERVAL   7       /* days */
+
+typedef struct private_stroke_t private_stroke_t;
+typedef struct stroke_credentials_t stroke_credentials_t;
+typedef struct ca_creds_t ca_creds_t;
+typedef struct creds_t creds_t;
+typedef struct ca_section_t ca_section_t;
+typedef struct configs_t configs_t;
+
+/**
+ * loaded ipsec.conf CA sections
+ */
+struct ca_section_t {
+
+       /**
+        * name of the CA section
+        */
+       char *name;
+       
+       /**
+        * reference to cert in trusted_credential_t
+        */
+       certificate_t *cert;
+       
+       /**
+        * CRL URIs
+        */
+       linked_list_t *crl;
+       
+       /**
+        * OCSP URIs
+        */
+       linked_list_t *ocsp;
+};
+
+/**
+ * private credentail_set_t implementation for CA sections
+ */
+struct ca_creds_t {
+       /**
+        * implements credential set
+        */
+       credential_set_t set;
+
+       /**
+        * list of starters CA sections and its certificates (ca_section_t)
+        */
+       linked_list_t *sections;
+       
+       /**
+        * mutex to lock sections list
+        */
+       mutex_t *mutex;
+       
+};
+
+/**
+ * private credential_set_t implementation for trusted certificates and keys
+ */
+struct creds_t {
+       /**
+        * implements credential set
+        */
+       credential_set_t set;
+       
+       /**
+        * list of trusted peer/signer/CA certificates (certificate_t)
+        */
+       linked_list_t *certs;
+
+       /**
+        * list of shared secrets (private_shared_key_t)
+        */
+       linked_list_t *shared;
+
+       /**
+        * list of private keys (private_key_t)
+        */
+       linked_list_t *private;
+       
+       /**
+        * mutex to lock lists above
+        */
+       mutex_t *mutex;
+};
+
+
+typedef struct private_shared_key_t private_shared_key_t;
+/**
+ * private data of shared_key
+ */
+struct private_shared_key_t {
+
+       /**
+        * implements shared_key_t
+        */
+       shared_key_t public;
+       
+       /**
+        * type of this key
+        */
+       shared_key_type_t type;
+
+       /**
+        * data of the key
+        */
+       chunk_t key;
+
+       /**
+        * list of key owners, as identification_t
+        */
+       linked_list_t *owners;
+       
+       /**
+        * reference counter
+        */
+       refcount_t ref;
+};
+
+
+/**
+ * configuration backend including peer_cfg list
+ */
+struct configs_t {
+
+       /**
+        * implements backend_t interface
+        */
+       backend_t backend;
+       
+       /**
+        * list of peer_cfg_t
+        */
+       linked_list_t *list;
+       
+       /**
+        * mutex to lock config list
+        */
+       mutex_t *mutex;
+};
+
+/**
+ * Private data of an stroke_t object.
+ */
+struct private_stroke_t {
+
+       /**
+        * Public part of stroke_t object.
+        */
+       stroke_t public;
+               
+       /**
+        * Unix socket to listen for strokes
+        */
+       int socket;
+       
+       /**
+        * job accepting stroke messages
+        */
+       callback_job_t *job;
+       
+       /**
+        * CA credentials
+        */
+       ca_creds_t ca_creds;
+       
+       /**
+        * other credentials
+        */
+       creds_t creds;
+       
+       /**
+        * configuration backend
+        */
+       configs_t configs;
+};
+
+typedef struct stroke_log_info_t stroke_log_info_t;
+
+/**
+ * helper struct to say what and where to log when using controller callback
+ */
+struct stroke_log_info_t {
+
+       /**
+        * level to log up to
+        */
+       level_t level;
+       
+       /**
+        * where to write log
+        */
+       FILE* out;
+};
+
+/**
+ * create a new CA section 
+ */
+static ca_section_t *ca_section_create(char *name, certificate_t *cert)
+{
+       ca_section_t *ca = malloc_thing(ca_section_t);
+       
+       ca->name = strdup(name);
+       ca->crl = linked_list_create();
+       ca->ocsp = linked_list_create();
+       ca->cert = cert;
+       return ca;
+}
+
+/**
+ * destroy a ca section entry
+ */
+static void ca_section_destroy(ca_section_t *this)
+{
+       this->crl->destroy_function(this->crl, free);
+       this->ocsp->destroy_function(this->ocsp, free);
+       free(this->name);
+       free(this);
+}
+
+/**
+ * another return NULL 
+ */
+static void* return_null()
+{
+       return NULL;
+}
+
+/**
+ * data to pass to create_inner_cdp
+ */
+typedef struct {
+       ca_creds_t *this;
+       certificate_type_t type;
+       identification_t *id;
+} cdp_data_t;
+
+/**
+ * destroy cdp enumerator data and unlock list
+ */
+static void cdp_data_destroy(cdp_data_t *data)
+{
+       data->this->mutex->unlock(data->this->mutex);
+       free(data);
+}
+
+/**
+ * inner enumerator constructor for CDP URIs
+ */
+static enumerator_t *create_inner_cdp(ca_section_t *section, cdp_data_t *data)
+{
+       public_key_t *public;
+       identification_t *keyid;
+       enumerator_t *enumerator = NULL;
+       linked_list_t *list;
+       
+       if (data->type == CERT_X509_OCSP_RESPONSE)
+       {
+               list = section->ocsp;
+       }
+       else
+       {
+               list = section->crl;
+       }
+
+       public = section->cert->get_public_key(section->cert);
+       if (public)
+       {
+               if (!data->id)
+               {
+                       enumerator = list->create_enumerator(list);
+               }
+               else
+               {
+                       keyid = public->get_id(public, data->id->get_type(data->id));
+                       if (keyid && keyid->matches(keyid, data->id))
+                       {
+                               enumerator = list->create_enumerator(list);             
+                       }
+               }
+               public->destroy(public);
+       }
+       return enumerator;
+}
+
+/**
+ * Implementation of ca_creds_t.set.create_cdp_enumerator.
+ */
+static enumerator_t *create_cdp_enumerator(ca_creds_t *this,
+                                                               certificate_type_t type, identification_t *id)
+{
+       cdp_data_t *data;
+
+       switch (type)
+       {       /* we serve CRLs and OCSP responders */
+               case CERT_X509_CRL:
+               case CERT_X509_OCSP_RESPONSE:
+               case CERT_ANY:
+                       break;
+               default:
+                       return NULL;
+       }
+       data = malloc_thing(cdp_data_t);
+       data->this = this;
+       data->type = type;
+       data->id = id;
+       
+       this->mutex->lock(this->mutex);
+       return enumerator_create_nested(this->sections->create_enumerator(this->sections),
+                                                                       (void*)create_inner_cdp, data,
+                                                                       (void*)cdp_data_destroy);
+}
+
+/**
+ * data to pass to various filters
+ */
+typedef struct {
+       creds_t *this;
+       identification_t *id;
+} id_data_t;
+
+/**
+ * destroy id enumerator data and unlock list
+ */
+static void id_data_destroy(id_data_t *data)
+{
+       data->this->mutex->unlock(data->this->mutex);
+       free(data);
+}
+
+
+/**
+ * filter function for private key enumerator
+ */
+static bool private_filter(id_data_t *data,
+                                                  private_key_t **in, private_key_t **out)
+{
+       identification_t *candidate;
+       
+       if (data->id == NULL)
+       {
+               *out = *in;
+               return TRUE;
+       }
+       candidate = (*in)->get_id(*in, data->id->get_type(data->id));
+       if (candidate && data->id->equals(data->id, candidate))
+       {
+               *out = *in;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * Implements creds_t.set.create_private_enumerator
+ */
+static enumerator_t* create_private_enumerator(creds_t *this,
+                                                       key_type_t type, identification_t *id)
+{
+       id_data_t *data;
+
+       if (type != KEY_RSA && type != KEY_ANY)
+       {       /* we only have RSA keys */
+               return NULL;
+       }
+       data = malloc_thing(id_data_t);
+       data->this = this;
+       data->id = id;
+       
+       this->mutex->lock(this->mutex);
+       return enumerator_create_filter(this->private->create_enumerator(this->private),
+                                                                       (void*)private_filter, data,
+                                                                       (void*)id_data_destroy);
+}
+
+/**
+ * filter function for certs enumerator
+ */
+static bool certs_filter(id_data_t *data, certificate_t **in, certificate_t **out)
+{
+       public_key_t *public;
+       identification_t *candidate;
+       certificate_t *cert = *in;
+       
+       if (cert->get_type(cert) == CERT_X509_CRL)
+       {
+               return FALSE;
+       }
+
+       if (data->id == NULL || cert->has_subject(cert, data->id))
+       {
+               *out = *in;
+               return TRUE;
+       }
+       
+       public = (cert)->get_public_key(cert);
+       if (public)
+       {
+               candidate = public->get_id(public, data->id->get_type(data->id));
+               if (candidate && data->id->equals(data->id, candidate))
+               {
+                       public->destroy(public);
+                       *out = *in;
+                       return TRUE;
+               }
+               public->destroy(public);
+       }
+       return FALSE;
+}
+
+/**
+ * filter function for crl enumerator
+ */
+static bool crl_filter(id_data_t *data, certificate_t **in, certificate_t **out)
+{
+       certificate_t *cert = *in;
+       
+       if (cert->get_type(cert) != CERT_X509_CRL)
+       {
+               return FALSE;
+       }
+
+       if (data->id == NULL || cert->has_issuer(cert, data->id))
+       {
+               *out = *in;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * Implements creds_t.set.create_cert_enumerator
+ */
+static enumerator_t* create_cert_enumerator(creds_t *this,
+                                                       certificate_type_t cert, key_type_t key,
+                                                       identification_t *id, bool trusted)
+{
+       id_data_t *data;
+       
+       if (cert == CERT_X509_CRL)
+       {
+               data = malloc_thing(id_data_t);
+               data->this = this;
+               data->id = id;
+               
+               this->mutex->lock(this->mutex);
+               return enumerator_create_filter(this->certs->create_enumerator(this->certs),
+                                                                               (void*)crl_filter, data,
+                                                                               (void*)id_data_destroy);
+       }
+       if (cert != CERT_X509 && cert != CERT_ANY)
+       {       /* we only have X509 certificates. TODO: ACs? */
+               return NULL;
+       }
+       if (key != KEY_RSA && key != KEY_ANY)
+       {       /* we only have RSA keys */
+               return NULL;
+       }
+       data = malloc_thing(id_data_t);
+       data->this = this;
+       data->id = id;
+       
+       this->mutex->lock(this->mutex);
+       return enumerator_create_filter(this->certs->create_enumerator(this->certs),
+                                                                       (void*)certs_filter, data,
+                                                                       (void*)id_data_destroy);
+}
+
+/**
+ * Implementation of shared_key_t.get_type.
+ */
+static shared_key_type_t get_type(private_shared_key_t *this)
+{
+       return this->type;
+}
+
+/**
+ * Implementation of shared_key_t.get_ref.
+ */
+static private_shared_key_t* get_ref(private_shared_key_t *this)
+{
+       ref_get(&this->ref);
+       return this;
+}
+
+/**
+ * Implementation of shared_key_t.destroy
+ */
+static void shared_key_destroy(private_shared_key_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               this->owners->destroy_offset(this->owners, offsetof(identification_t, destroy));
+               chunk_free(&this->key);
+               free(this);
+       }
+}
+
+/**
+ * Implementation of shared_key_t.get_key.
+ */
+static chunk_t get_key(private_shared_key_t *this)
+{
+       return this->key;
+}
+
+/**
+ * create a shared key
+ */
+static private_shared_key_t *shared_key_create(shared_key_type_t type, chunk_t key)
+{
+       private_shared_key_t *this = malloc_thing(private_shared_key_t);
+
+       this->public.get_type = (shared_key_type_t(*)(shared_key_t*))get_type;
+       this->public.get_key = (chunk_t(*)(shared_key_t*))get_key;
+       this->public.get_ref = (shared_key_t*(*)(shared_key_t*))get_ref;
+       this->public.destroy = (void(*)(shared_key_t*))shared_key_destroy;
+
+       this->owners = linked_list_create();
+       this->type = type;
+       this->key = key;
+       this->ref = 1;
+       return this;
+}
+
+/**
+ * Check if a key has such an owner
+ */
+static id_match_t has_owner(private_shared_key_t *this, identification_t *owner)
+{
+       enumerator_t *enumerator;
+       id_match_t match, best = ID_MATCH_NONE;
+       identification_t *current;
+       
+       enumerator = this->owners->create_enumerator(this->owners);
+       while (enumerator->enumerate(enumerator, &current))
+       {
+               match  = owner->matches(owner, current);
+               if (match > best)
+               {
+                       best = match;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return best;
+}
+
+typedef struct {
+       creds_t *this;
+       identification_t *me;
+       identification_t *other;
+       shared_key_type_t type;
+} shared_data_t;
+
+/**
+ * free shared key enumerator data and unlock list
+ */
+static void shared_data_destroy(shared_data_t *data)
+{
+       data->this->mutex->unlock(data->this->mutex);
+       free(data);
+}
+
+/**
+ * filter function for certs enumerator
+ */
+static bool shared_filter(shared_data_t *data,
+                                                 private_shared_key_t **in, private_shared_key_t **out,
+                                                 void **unused1, id_match_t *me,
+                                                 void **unused2, id_match_t *other)
+{
+       id_match_t my_match, other_match;
+
+       if (!(*in)->type == SHARED_ANY && !(*in)->type == data->type)
+       {
+               return FALSE;
+       }
+       my_match = has_owner(*in, data->me);
+       other_match = has_owner(*in, data->other);
+       if (!my_match && !other_match)
+       {
+               return FALSE;
+       }
+       *out = *in;
+       if (me)
+       {
+               *me = my_match;
+       }
+       if (other)
+       {
+               *other = other_match;
+       }
+       return TRUE;
+}
+
+/**
+ * Implements creds_t.set.create_shared_enumerator
+ */
+static enumerator_t* create_shared_enumerator(creds_t *this, 
+                                                       shared_key_type_t type, identification_t *me,
+                                                       identification_t *other)
+{
+       shared_data_t *data = malloc_thing(shared_data_t);
+       
+       data->this = this;
+       data->me = me;
+       data->other = other;
+       data->type = type;
+       this->mutex->lock(this->mutex);
+       return enumerator_create_filter(this->shared->create_enumerator(this->shared),
+                                                                       (void*)shared_filter, data,
+                                                                       (void*)shared_data_destroy);
+}
+
+/**
+ * Helper function which corrects the string pointers
+ * in a stroke_msg_t. Strings in a stroke_msg sent over "wire"
+ * contains RELATIVE addresses (relative to the beginning of the
+ * stroke_msg). They must be corrected if they reach our address
+ * space...
+ */
+static void pop_string(stroke_msg_t *msg, char **string)
+{
+       if (*string == NULL)
+       {
+               return;
+       }
+
+       /* check for sanity of string pointer and string */
+       if (string < (char**)msg ||
+               string > (char**)msg + sizeof(stroke_msg_t) ||
+               (unsigned long)*string < (unsigned long)((char*)msg->buffer - (char*)msg) ||
+               (unsigned long)*string > msg->length)
+       {
+               *string = "(invalid pointer in stroke msg)";
+       }
+       else
+       {
+               *string = (char*)msg + (unsigned long)*string;
+       }
+}
+
+/**
+ * Load an X.509 certificate
+ */
+static x509_t* load_cert(char *path, x509_flag_t flag)
+{
+       bool pgp = FALSE;
+       chunk_t chunk;
+       x509_flag_t flags;
+       x509_t *x509;
+       certificate_t *cert;
+       
+       if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
+       {
+               DBG1(DBG_CFG, "  could not load certificate file '%s'", path);
+               return NULL;
+       }
+       x509 = (x509_t*)lib->creds->create(lib->creds,
+                                                                          CRED_CERTIFICATE, CERT_X509,
+                                                                          BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+       if (x509 == NULL)
+       {
+               DBG1(DBG_CFG, "  could not load certificate file '%s'", path);
+               return NULL;
+       }
+       DBG1(DBG_CFG, "  loaded certificate file '%s'", path);
+
+       cert = &x509->interface;
+       flags = x509->get_flags(x509);
+
+       /* check basicConstraints */
+       if ((flag & X509_CA)  && !(flags & X509_CA))
+       {
+               DBG1(DBG_CFG, "  isCA basicConstraint is not set, certificate discarded");
+               cert->destroy(cert);
+               return NULL;
+       }
+
+       /* set cert flags to flag but keep X509_SELF_SIGNED property */
+       x509->set_flags(x509, flag | (flags & X509_SELF_SIGNED));
+               
+       /* check validity */
+       {
+               time_t notBefore, notAfter, now = time(NULL);
+
+               cert->get_validity(cert, &now, &notBefore, &notAfter);
+               if (now > notAfter)
+               {
+                       DBG1(DBG_CFG, "  certificate expired at %T, discarded", &notAfter);
+                       cert->destroy(cert);
+                       return NULL;
+               }
+               if (now < notBefore)
+               {
+                       DBG1(DBG_CFG, "  certificate not valid before %T", &notBefore);
+               }
+       }
+       return x509;
+}
+
+/**
+ * Add X.509 certificate to chain
+ */
+static certificate_t* add_x509_cert(private_stroke_t *this, x509_t* x509)
+{
+       certificate_t *current, *cert = &x509->interface;
+       enumerator_t *enumerator;
+       bool new = TRUE;        
+
+       this->creds.mutex->lock(this->creds.mutex);
+       enumerator = this->creds.certs->create_enumerator(this->creds.certs);
+       while (enumerator->enumerate(enumerator, (void**)&current))
+       {
+               if (current->equals(current, cert))
+               {
+                       x509_flag_t flags = x509->get_flags(x509);
+                       x509_t *x509c = (x509_t*)current;
+
+                       /* cert already in queue - add flags and discard */
+                       x509c->set_flags(x509c, flags | x509c->get_flags(x509c));
+                       cert->destroy(cert);
+                       cert = current;
+                       new = FALSE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       if (new)
+       {
+               this->creds.certs->insert_last(this->creds.certs, cert);
+       }
+       this->creds.mutex->unlock(this->creds.mutex);
+       return cert;
+}
+
+/**
+ * Verify the signature of an X.509 CRL
+ */
+static bool verify_crl(crl_t* crl)
+{
+       certificate_t *crl_cert = &crl->certificate;
+       identification_t *issuer = crl_cert->get_issuer(crl_cert);
+       identification_t *authKeyIdentifier = crl->get_authKeyIdentifier(crl);
+       certificate_t *issuer_cert;
+
+       DBG1(DBG_CFG, "  issuer: %D", issuer);
+       if (authKeyIdentifier)
+       {
+               DBG1(DBG_CFG, "  authkey: %D", authKeyIdentifier);
+       }
+
+       issuer_cert = charon->credentials->get_cert(charon->credentials, CERT_X509,
+                                                                                           KEY_ANY, issuer, TRUE);
+
+       if (issuer_cert)
+       {
+               
+               bool ok = crl_cert->issued_by(crl_cert, issuer_cert, TRUE);
+
+               DBG1(DBG_CFG, "  crl is %strusted: %s signature",
+                                                ok? "":"un", ok? "good":"bad");
+               return ok;
+       }
+       else
+       {
+               DBG1(DBG_CFG, "  crl is untrusted: issuer certificate not found");
+               return FALSE;
+       }
+}
+
+/**
+ * Add X.509 CRL to chain
+ */
+static void add_crl(private_stroke_t *this, crl_t* crl)
+{
+       certificate_t *current, *cert = &crl->certificate;
+       enumerator_t *enumerator;
+       bool new = TRUE, found = FALSE; 
+
+       this->creds.mutex->lock(this->creds.mutex);
+       enumerator = this->creds.certs->create_enumerator(this->creds.certs);
+       while (enumerator->enumerate(enumerator, (void**)&current))
+       {
+               if (current->get_type(current) == CERT_X509_CRL)
+               {
+                       crl_t *crl_c = (crl_t*)current;
+                       identification_t *authkey = crl->get_authKeyIdentifier(crl);
+                       identification_t *authkey_c = crl_c->get_authKeyIdentifier(crl_c);
+
+                       /* if compare authorityKeyIdentifiers if available */
+                       if (authkey != NULL && authkey_c != NULL &&
+                               authkey->equals(authkey, authkey_c))
+                       {
+                               found = TRUE;
+                       }
+                       else
+                       {
+                               identification_t *issuer = cert->get_issuer(cert);
+                               identification_t *issuer_c = current->get_issuer(current);
+
+                               /* otherwise compare issuer distinguished names */
+                               if (issuer->equals(issuer, issuer_c))
+                               {
+                                       found = TRUE;
+                               }
+                       }
+                       if (found)
+                       {
+                               new = crl->is_newer(crl, crl_c);
+                               if (new)
+                               {
+                                       this->creds.certs->remove_at(this->creds.certs, enumerator);
+                               }
+                               else
+                               {
+                                       cert->destroy(cert);
+                               }
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       if (new)
+       {
+               this->creds.certs->insert_last(this->creds.certs, cert);
+       }
+       this->creds.mutex->unlock(this->creds.mutex);
+}
+
+/**
+ * Load end entitity certificate
+ */
+static void load_peer_cert(private_stroke_t *this,
+                                                  char *filename, identification_t **id)
+{
+       char path[PATH_MAX];
+       x509_t *x509;
+       identification_t *peerid = *id;
+
+       if (*filename == '/')
+       {
+               snprintf(path, sizeof(path), "%s", filename);
+       }
+       else
+       {
+               snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
+       }
+       
+       x509 = load_cert(path, X509_PEER);
+
+       if (x509)
+       {
+               certificate_t *cert = &x509->interface;;
+               identification_t *subject = cert->get_subject(cert);
+
+               if (!cert->has_subject(cert, peerid))
+               {
+                       DBG1(DBG_CFG, "  peerid %D not confirmed by certificate, "
+                                       "defaulting to subject DN", peerid);
+                       peerid->destroy(peerid);
+                       *id = subject->clone(subject);
+               }
+               add_x509_cert(this, x509);
+       }
+}
+
+/**
+ * Load ca certificate
+ */
+static certificate_t* load_ca_cert(private_stroke_t *this, char *filename)
+{
+       char path[PATH_MAX];
+       x509_t *x509;
+
+       if (*filename == '/')
+       {
+               snprintf(path, sizeof(path), "%s", filename);
+       }
+       else
+       {
+               snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
+       }
+       
+       x509 = load_cert(path, X509_CA);
+
+       if (x509)
+       {
+               return add_x509_cert(this, x509);
+       }
+       else
+       {
+               return NULL;
+       }
+}
+
+/**
+ * load trusted certificates from a directory
+ */
+static void load_certdir(private_stroke_t *this,
+                                                char *path, certificate_type_t type, x509_flag_t flag)
+{
+       struct stat st;
+       char *file;
+       
+       enumerator_t *enumerator = enumerator_create_directory(path);
+
+       if (!enumerator)
+       {
+               DBG1(DBG_CFG, "  reading directory failed");
+               return;
+       }
+
+       while (enumerator->enumerate(enumerator, NULL, &file, &st))
+       {
+               if (!S_ISREG(st.st_mode))
+               {
+                       /* skip special file */
+                       continue;
+               }
+               if (type == CERT_X509)
+               {
+                       x509_t *x509 = load_cert(file, flag);
+
+                       if (x509)
+                       {
+                               add_x509_cert(this, x509);
+                       }
+               }
+               else
+               {       
+                       certificate_t *cert;
+                       bool pgp = FALSE;
+                       chunk_t chunk;
+       
+                       if (!pem_asn1_load_file(file, NULL, &chunk, &pgp))
+                       {
+                               continue;
+                       }
+                       cert = lib->creds->create(lib->creds,
+                                                                         CRED_CERTIFICATE, type,
+                                                                         BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+                       if (type == CERT_X509_CRL)
+                       {
+                               if (cert)
+                               {
+                                       crl_t *crl = (crl_t*)cert;
+
+                                       DBG1(DBG_CFG, "  loaded crl file '%s'", file);
+
+                                       /* only trusted crls are added to the store */
+                                       if (verify_crl(crl))
+                                       {
+                                               add_crl(this, crl);
+                                       }
+                                       else
+                                       {
+                                               DBG1(DBG_CFG, "  crl discarded");
+                                               cert->destroy(cert);
+                                       }
+                               }
+                               else 
+                               {
+                                       DBG1(DBG_CFG, " could not load crl file '%s'", file);
+                               }
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+}
+
+/**
+ * Convert a string of characters into a binary secret
+ * A string between single or double quotes is treated as ASCII characters
+ * A string prepended by 0x is treated as HEX and prepended by 0s as Base64
+ */
+static err_t extract_secret(chunk_t *secret, chunk_t *line)
+{
+       chunk_t raw_secret;
+       char delimiter = ' ';
+       bool quotes = FALSE;
+
+       if (!eat_whitespace(line))
+       {
+               return "missing secret";
+       }
+
+       if (*line->ptr == '\'' || *line->ptr == '"')
+       {
+               quotes = TRUE;
+               delimiter = *line->ptr;
+               line->ptr++;  line->len--;
+       }
+
+       if (!extract_token(&raw_secret, delimiter, line))
+       {
+               if (delimiter == ' ')
+               {
+                       raw_secret = *line;
+               }
+               else
+               {
+                       return "missing second delimiter";
+               }
+       }
+
+       if (quotes)
+       {       
+               /* treat as an ASCII string */
+               *secret = chunk_clone(raw_secret);
+       }
+       else
+       {
+               size_t len;
+               err_t ugh;
+
+               /* secret converted to binary form doesn't use more space than the raw_secret */
+               *secret = chunk_alloc(raw_secret.len);
+
+               /* convert from HEX or Base64 to binary */
+               ugh = ttodata(raw_secret.ptr, raw_secret.len, 0, secret->ptr, secret->len, &len);
+
+           if (ugh != NULL)
+               {
+                       chunk_free_randomized(secret);
+                       return ugh;
+               }
+               secret->len = len;
+       }
+       return NULL;
+}
+
+/**
+ * reload ipsec.secrets
+ */
+static void load_secrets(private_stroke_t *this)
+{
+       size_t bytes;
+       int line_nr = 0;
+       chunk_t chunk, src, line;
+       FILE *fd;
+       private_key_t *private;
+       shared_key_t *shared;
+
+       DBG1(DBG_CFG, "loading secrets from '%s'", SECRETS_FILE);
+
+       fd = fopen(SECRETS_FILE, "r");
+       if (fd == NULL)
+       {
+               DBG1(DBG_CFG, "opening secrets file '%s' failed");
+               return;
+       }
+
+       /* TODO: do error checks */
+       fseek(fd, 0, SEEK_END);
+       chunk.len = ftell(fd);
+       rewind(fd);
+       chunk.ptr = malloc(chunk.len);
+       bytes = fread(chunk.ptr, 1, chunk.len, fd);
+       fclose(fd);
+       src = chunk;
+
+       this->creds.mutex->lock(this->creds.mutex);
+       while (this->creds.shared->remove_last(this->creds.shared,
+                                                                                  (void**)&shared) == SUCCESS)
+       {
+               shared->destroy(shared);
+       }
+       while (this->creds.private->remove_last(this->creds.private,
+                                                                                   (void**)&private) == SUCCESS)
+       {
+               private->destroy(private);
+       }
+       
+       while (fetchline(&src, &line))
+       {
+               chunk_t ids, token;
+               shared_key_type_t type;
+
+               line_nr++;
+
+               if (!eat_whitespace(&line))
+               {
+                       continue;
+               }
+               if (!extract_token(&ids, ':', &line))
+               {
+                       DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr);
+                       goto error;
+               }
+               /* NULL terminate the ids string by replacing the : separator */
+               *(ids.ptr + ids.len) = '\0';
+
+               if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
+               {
+                       DBG1(DBG_CFG, "line %d: missing token", line_nr);
+                       goto error;
+               }
+               if (match("RSA", &token))
+               {
+                       char path[PATH_MAX];
+                       chunk_t filename;
+                       chunk_t secret = chunk_empty;
+                       private_key_t *key;
+                       bool pgp = FALSE;
+                       chunk_t chunk = chunk_empty;
+
+                       err_t ugh = extract_value(&filename, &line);
+
+                       if (ugh != NULL)
+                       {
+                               DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
+                               goto error;
+                       }
+                       if (filename.len == 0)
+                       {
+                               DBG1(DBG_CFG, "line %d: empty filename", line_nr);
+                               goto error;
+                       }
+                       if (*filename.ptr == '/')
+                       {
+                               /* absolute path name */
+                               snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
+                       }
+                       else
+                       {
+                               /* relative path name */
+                               snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR, 
+                                                filename.len, filename.ptr);
+                       }
+
+                       /* check for optional passphrase */
+                       if (eat_whitespace(&line))
+                       {
+                               ugh = extract_secret(&secret, &line);
+                               if (ugh != NULL)
+                               {
+                                       DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
+                                       goto error;
+                               }
+                       }
+
+                       if (pem_asn1_load_file(path, &secret, &chunk, &pgp))
+                       {
+                               key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+                                                                                BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+                               if (key)
+                               {
+                                       DBG1(DBG_CFG, "  loaded private key file '%s'", path);
+                                       this->creds.private->insert_last(this->creds.private, key);
+                               }
+                       }
+                       chunk_free_randomized(&secret);
+               }
+               else if ((match("PSK", &token) && (type = SHARED_IKE)) ||
+                                (match("EAP", &token) && (type = SHARED_EAP)) ||
+                                (match("XAUTH", &token) && (type = SHARED_EAP)) ||
+                                (match("PIN", &token) && (type = SHARED_PIN)))
+               {
+                       private_shared_key_t *shared_key;
+                       chunk_t secret = chunk_empty;
+                       bool any = TRUE;
+
+                       err_t ugh = extract_secret(&secret, &line);
+                       if (ugh != NULL)
+                       {
+                               DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
+                               goto error;
+                       }
+                       shared_key = shared_key_create(type, secret);
+                       DBG1(DBG_CFG, "  loaded %N secret for %s", shared_key_type_names, type,
+                                ids.len > 0 ? (char*)ids.ptr : "%any");
+                       DBG4(DBG_CFG, "  secret:", secret);
+                       
+                       this->creds.shared->insert_last(this->creds.shared, shared_key);
+                       while (ids.len > 0)
+                       {
+                               chunk_t id;
+                               identification_t *peer_id;
+
+                               ugh = extract_value(&id, &ids);
+                               if (ugh != NULL)
+                               {
+                                       DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
+                                       goto error;
+                               }
+                               if (id.len == 0)
+                               {
+                                       continue;
+                               }
+
+                               /* 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;
+                               }
+                               
+                               shared_key->owners->insert_last(shared_key->owners, peer_id);
+                               any = FALSE;
+                       }
+                       if (any)
+                       {
+                               shared_key->owners->insert_last(shared_key->owners,
+                                       identification_create_from_encoding(ID_ANY, chunk_empty));
+                       }
+               }
+               else
+               {
+                       DBG1(DBG_CFG, "line %d: token must be either "
+                                "RSA, PSK, EAP, or PIN", line_nr);
+                       goto error;
+               }
+       }
+error:
+       this->creds.mutex->unlock(this->creds.mutex);
+       chunk_free_randomized(&chunk);
+}
+
+/**
+ * data to pass peer_filter
+ */
+typedef struct {
+       configs_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)
+{
+
+       if ((!data->me || data->me->matches(data->me, (*in)->get_my_id(*in))) &&
+               (!data->other || data->other->matches(data->other, (*in)->get_other_id(*in))))
+       {
+               *out = *in;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * Implementation of backend_t.create_peer_cfg_enumerator.
+ */
+static enumerator_t* create_peer_cfg_enumerator(configs_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 {
+       configs_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);
+}
+
+/**
+ * filter function for ike configs
+ */
+static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
+{
+       ike_cfg_t *ike_cfg;
+       host_t *me, *other;
+       
+       ike_cfg = (*in)->get_ike_cfg(*in);
+       
+       me = ike_cfg->get_my_host(ike_cfg);
+       other = ike_cfg->get_other_host(ike_cfg);
+       if ((!data->me || me->is_anyaddr(me) || me->ip_equals(me, data->me)) &&
+               (!data->other || other->is_anyaddr(other) || other->ip_equals(other, data->me)))
+       {
+               *out = ike_cfg;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * Implementation of backend_t.create_ike_cfg_enumerator.
+ */
+static enumerator_t* create_ike_cfg_enumerator(configs_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);
+}
+
+/**
+ * implements backend_t.get_peer_cfg_by_name.
+ */
+static peer_cfg_t *get_peer_cfg_by_name(configs_t *this, char *name)
+{
+       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;
+        }
+       }
+       e1->destroy(e1);
+       this->mutex->unlock(this->mutex);
+       return found;
+}
+
+/**
+ * Pop the strings of a stroke_end_t struct and log them for debugging purposes
+ */
+static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
+{
+       pop_string(msg, &end->address);
+       pop_string(msg, &end->subnet);
+       pop_string(msg, &end->sourceip);
+       pop_string(msg, &end->id);
+       pop_string(msg, &end->cert);
+       pop_string(msg, &end->ca);
+       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->subnet);
+       DBG2(DBG_CFG, "  %ssourceip=%s", label, end->sourceip);
+       DBG2(DBG_CFG, "  %sid=%s", label, end->id);
+       DBG2(DBG_CFG, "  %scert=%s", label, end->cert);
+       DBG2(DBG_CFG, "  %sca=%s", label, end->ca);
+       DBG2(DBG_CFG, "  %sgroups=%s", label, end->groups);
+       DBG2(DBG_CFG, "  %supdown=%s", label, end->updown);
+}
+
+/**
+ * Add a connection to the configuration list
+ */
+static void stroke_add_conn(private_stroke_t *this,
+                                                       stroke_msg_t *msg, FILE *out)
+{
+       ike_cfg_t *ike_cfg;
+       peer_cfg_t *peer_cfg;
+       peer_cfg_t *mediated_by_cfg = NULL;
+       child_cfg_t *child_cfg;
+       auth_info_t *auth;
+       identification_t *my_id, *other_id;
+       identification_t *my_ca = NULL;
+       identification_t *other_ca = NULL;
+       identification_t *peer_id = NULL;
+       bool my_ca_same = FALSE;
+       bool other_ca_same =FALSE;
+       host_t *my_host = NULL, *other_host = NULL, *my_subnet, *other_subnet;
+       host_t *my_vip = NULL, *other_vip = NULL;
+       proposal_t *proposal;
+       traffic_selector_t *my_ts, *other_ts;
+       char *interface;
+       bool use_existing = FALSE;
+       enumerator_t *enumerator;
+       u_int32_t vendor;
+       
+       pop_string(msg, &msg->add_conn.name);
+       DBG1(DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);
+       DBG2(DBG_CFG, "conn %s", msg->add_conn.name);
+       pop_end(msg, "left", &msg->add_conn.me);
+       pop_end(msg, "right", &msg->add_conn.other);
+       pop_string(msg, &msg->add_conn.algorithms.ike);
+       pop_string(msg, &msg->add_conn.algorithms.esp);
+       DBG2(DBG_CFG, "  ike=%s", msg->add_conn.algorithms.ike);
+       DBG2(DBG_CFG, "  esp=%s", msg->add_conn.algorithms.esp);
+       pop_string(msg, &msg->add_conn.p2p.mediated_by);
+       pop_string(msg, &msg->add_conn.p2p.peerid);
+       DBG2(DBG_CFG, "  p2p_mediation=%s", msg->add_conn.p2p.mediation ? "yes" : "no");
+       DBG2(DBG_CFG, "  p2p_mediated_by=%s", msg->add_conn.p2p.mediated_by);
+       DBG2(DBG_CFG, "  p2p_peerid=%s", msg->add_conn.p2p.peerid);
+       
+       if (msg->add_conn.me.address)
+       {
+               my_host = host_create_from_string(msg->add_conn.me.address,
+                                                                                 IKEV2_UDP_PORT);
+       }
+       if (my_host == NULL)
+       {
+               DBG1(DBG_CFG, "invalid host: %s\n", msg->add_conn.me.address);
+               return;
+       }
+       if (msg->add_conn.other.address)
+       {
+               other_host = host_create_from_string(msg->add_conn.other.address,
+                                                                                        IKEV2_UDP_PORT);
+       }
+       if (other_host == NULL)
+       {
+               DBG1(DBG_CFG, "invalid host: %s\n", msg->add_conn.other.address);
+               my_host->destroy(my_host);
+               return;
+       }
+       
+       interface = charon->kernel_interface->get_interface(charon->kernel_interface, 
+                                                                                                               other_host);
+       if (interface)
+       {
+               stroke_end_t tmp_end;
+               host_t *tmp_host;
+
+               DBG2(DBG_CFG, "left is other host, swapping ends\n");
+
+               tmp_host = my_host;
+               my_host = other_host;
+               other_host = tmp_host;
+
+               tmp_end = msg->add_conn.me;
+               msg->add_conn.me = msg->add_conn.other;
+               msg->add_conn.other = tmp_end;
+               free(interface);
+       }
+       else
+       {
+               interface = charon->kernel_interface->get_interface(
+                                                                                       charon->kernel_interface, my_host);
+               if (!interface)
+               {
+                       DBG1(DBG_CFG, "left nor right host is our side, assuming left=local");
+               }
+               else
+               {
+                       free(interface);
+               }
+       }
+
+       my_id = identification_create_from_string(msg->add_conn.me.id ?
+                                               msg->add_conn.me.id : msg->add_conn.me.address);
+       if (my_id == NULL)
+       {
+               DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.me.id);
+               goto destroy_hosts;
+       }
+
+       other_id = identification_create_from_string(msg->add_conn.other.id ?
+                                               msg->add_conn.other.id : msg->add_conn.other.address);
+       if (other_id == NULL)
+       {
+               DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.other.id);
+               my_id->destroy(my_id);
+               goto destroy_hosts;
+       }
+       
+#ifdef P2P
+       if (msg->add_conn.p2p.mediation && msg->add_conn.p2p.mediated_by)
+       {
+               DBG1(DBG_CFG, "a mediation connection cannot be a"
+                               " mediated connection at the same time, aborting");
+               goto destroy_ids;
+       }
+       
+       if (msg->add_conn.p2p.mediated_by)
+       {
+               mediated_by_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
+                                                                                               msg->add_conn.p2p.mediated_by);
+               if (!mediated_by_cfg)
+               {
+                       DBG1(DBG_CFG, "mediation connection '%s' not found, aborting",
+                                       msg->add_conn.p2p.mediated_by);
+                       goto destroy_ids;
+               }
+               
+               if (!mediated_by_cfg->is_mediation(mediated_by_cfg))
+               {
+                       DBG1(DBG_CFG, "connection '%s' as referred to by '%s' is"
+                                       "no mediation connection, aborting", 
+                                       msg->add_conn.p2p.mediated_by, msg->add_conn.name);
+                       goto destroy_ids;
+               }
+       }
+       
+       if (msg->add_conn.p2p.peerid)
+       {
+               peer_id = identification_create_from_string(msg->add_conn.p2p.peerid);
+               if (!peer_id)
+               {
+                       DBG1(DBG_CFG, "invalid peer ID: %s\n", msg->add_conn.p2p.peerid);
+                       goto destroy_ids;
+               }
+       }
+       else
+       {
+               /* no peer ID supplied, assume right ID */
+               peer_id = other_id->clone(other_id);
+       }
+#endif /* P2P */
+       
+       my_subnet = host_create_from_string(
+                                                       msg->add_conn.me.subnet ? msg->add_conn.me.subnet
+                                                                                                       : msg->add_conn.me.address, 
+                                                       IKEV2_UDP_PORT);
+       if (my_subnet == NULL)
+       {
+               DBG1(DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
+               goto destroy_ids;
+       }
+       
+       other_subnet = host_create_from_string(
+                                               msg->add_conn.other.subnet ? msg->add_conn.other.subnet 
+                                                                                                  : msg->add_conn.other.address, 
+                                               IKEV2_UDP_PORT);
+       if (other_subnet == NULL)
+       {
+               DBG1(DBG_CFG, "invalid subnet: %s\n", msg->add_conn.me.subnet);
+               my_subnet->destroy(my_subnet);
+               goto destroy_ids;
+       }
+       
+       if (msg->add_conn.me.virtual_ip && msg->add_conn.me.sourceip)
+       {
+               my_vip = host_create_from_string(msg->add_conn.me.sourceip, 0);
+       }
+       if (msg->add_conn.other.virtual_ip && msg->add_conn.other.sourceip)
+       {
+               other_vip = host_create_from_string(msg->add_conn.other.sourceip, 0);
+       }
+       
+       if (msg->add_conn.me.tohost)
+       {
+               my_ts = traffic_selector_create_dynamic(msg->add_conn.me.protocol,
+                                       my_host->get_family(my_host) == AF_INET ?
+                                               TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE,
+                                       msg->add_conn.me.port ? msg->add_conn.me.port : 0,
+                                       msg->add_conn.me.port ? msg->add_conn.me.port : 65535);
+       }
+       else
+       {
+               my_ts = traffic_selector_create_from_subnet(my_subnet,
+                               msg->add_conn.me.subnet ?  msg->add_conn.me.subnet_mask : 0,
+                               msg->add_conn.me.protocol, msg->add_conn.me.port);
+       }
+       my_subnet->destroy(my_subnet);
+       
+       if (msg->add_conn.other.tohost)
+       {
+               other_ts = traffic_selector_create_dynamic(msg->add_conn.other.protocol,
+                                       other_host->get_family(other_host) == AF_INET ?
+                                               TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE,
+                                       msg->add_conn.other.port ? msg->add_conn.other.port : 0,
+                                       msg->add_conn.other.port ? msg->add_conn.other.port : 65535);
+       }
+       else
+       {
+               other_ts = traffic_selector_create_from_subnet(other_subnet, 
+                               msg->add_conn.other.subnet ?  msg->add_conn.other.subnet_mask : 0,
+                               msg->add_conn.other.protocol, msg->add_conn.other.port);
+       }
+       other_subnet->destroy(other_subnet);
+
+       if (msg->add_conn.me.ca)
+       {
+               if (streq(msg->add_conn.me.ca, "%same"))
+               {
+                       my_ca_same = TRUE;
+               }
+               else
+               {
+                       my_ca = identification_create_from_string(msg->add_conn.me.ca);
+               }
+       }
+       if (msg->add_conn.other.ca)
+       {
+               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 (msg->add_conn.me.cert)
+       {
+               load_peer_cert(this, msg->add_conn.me.cert, &my_id);
+       }
+       if (msg->add_conn.other.cert)
+       {
+               load_peer_cert(this, msg->add_conn.other.cert, &other_id);
+       }
+       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 (my_ca)
+       {
+               DBG2(DBG_CFG, "  my ca:    %D", my_ca);
+       }
+       if (other_ca)
+       {
+               DBG2(DBG_CFG, "  other ca: %D", other_ca);
+       }
+
+       if (msg->add_conn.other.groups)
+       {
+               /* TODO: AC groups */
+       }
+
+       /* TODO: update matching */
+       /* have a look for an (almost) identical peer config to reuse */
+       enumerator = create_peer_cfg_enumerator(&this->configs, NULL, NULL);
+       while (enumerator->enumerate(enumerator, &peer_cfg))
+       {
+               host_t *my_vip_conf, *other_vip_conf;
+               bool my_vip_equals = FALSE, other_vip_equals = FALSE;
+
+               my_vip_conf = peer_cfg->get_my_virtual_ip(peer_cfg);
+               if ((my_vip && my_vip_conf && my_vip->equals(my_vip, my_vip_conf)) ||
+                       (!my_vip_conf && !my_vip))
+               {
+                       my_vip_equals = TRUE;
+               }
+               DESTROY_IF(my_vip_conf);
+               other_vip_conf = peer_cfg->get_other_virtual_ip(peer_cfg, NULL);
+               if ((other_vip && other_vip_conf && other_vip->equals(other_vip, other_vip_conf)) ||
+                       (!other_vip_conf && !other_vip))
+               {
+                       other_vip_equals = TRUE;
+               }
+               DESTROY_IF(other_vip_conf);
+       
+               ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
+               if (my_id->equals(my_id, peer_cfg->get_my_id(peer_cfg))
+               &&      other_id->equals(other_id, peer_cfg->get_other_id(peer_cfg))
+               &&      my_host->equals(my_host, ike_cfg->get_my_host(ike_cfg))
+               &&      other_host->equals(other_host, ike_cfg->get_other_host(ike_cfg))
+               &&      peer_cfg->get_ike_version(peer_cfg) == (msg->add_conn.ikev2 ? 2 : 1)
+               &&      peer_cfg->get_auth_method(peer_cfg) == msg->add_conn.auth_method
+               &&      peer_cfg->get_eap_type(peer_cfg, &vendor) == msg->add_conn.eap_type
+               &&  vendor == msg->add_conn.eap_vendor
+               &&  my_vip_equals && other_vip_equals)
+               {
+                       DBG1(DBG_CFG, "reusing existing configuration '%s'",
+                                peer_cfg->get_name(peer_cfg));
+                       use_existing = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       if (use_existing)
+       {
+               DESTROY_IF(my_vip);
+               DESTROY_IF(other_vip);
+               my_host->destroy(my_host);
+               my_id->destroy(my_id);
+               DESTROY_IF(my_ca);
+               other_host->destroy(other_host);
+               other_id->destroy(other_id);
+               DESTROY_IF(other_ca);
+               DESTROY_IF(peer_id);
+               DESTROY_IF(mediated_by_cfg);
+       }
+       else
+       {
+               ike_cfg = ike_cfg_create(msg->add_conn.other.sendcert != CERT_NEVER_SEND,
+                                                                msg->add_conn.force_encap, my_host, other_host);
+
+               if (msg->add_conn.algorithms.ike)
+               {
+                       char *proposal_string;
+                       char *strict = msg->add_conn.algorithms.ike + strlen(msg->add_conn.algorithms.ike) - 1;
+
+                       if (*strict == '!')
+                               *strict = '\0';
+                       else
+                               strict = NULL;
+
+                       while ((proposal_string = strsep(&msg->add_conn.algorithms.ike, ",")))
+                       {
+                               proposal = proposal_create_from_string(PROTO_IKE, proposal_string);
+                               if (proposal == NULL)
+                               {
+                                       DBG1(DBG_CFG, "invalid IKE proposal string: %s", proposal_string);
+                                       my_id->destroy(my_id);
+                                       other_id->destroy(other_id);
+                                       my_ts->destroy(my_ts);
+                                       other_ts->destroy(other_ts);
+                                       DESTROY_IF(my_ca);
+                                       DESTROY_IF(other_ca);
+                                       ike_cfg->destroy(ike_cfg);
+                                       return;
+                               }
+                               ike_cfg->add_proposal(ike_cfg, proposal);
+                       }
+                       if (!strict)
+                       {
+                               proposal = proposal_create_default(PROTO_IKE);
+                               ike_cfg->add_proposal(ike_cfg, proposal);
+                       }
+               }
+               else
+               {
+                       proposal = proposal_create_default(PROTO_IKE);
+                       ike_cfg->add_proposal(ike_cfg, proposal);
+               }
+               
+               u_int32_t rekey = 0, reauth = 0, over, jitter;
+               cert_validation_t valid;
+               
+               jitter = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;
+               over = msg->add_conn.rekey.margin;
+               if (msg->add_conn.rekey.reauth)
+               {
+                       reauth = msg->add_conn.rekey.ike_lifetime - over;
+               }
+               else
+               {
+                       rekey = msg->add_conn.rekey.ike_lifetime - over;
+               }
+               
+               peer_cfg = peer_cfg_create(msg->add_conn.name,
+                                       msg->add_conn.ikev2 ? 2 : 1, ike_cfg, my_id, other_id,
+                                       msg->add_conn.me.sendcert, msg->add_conn.auth_method,
+                                       msg->add_conn.eap_type, msg->add_conn.eap_vendor,
+                                       msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
+                                       msg->add_conn.mobike,
+                                       msg->add_conn.dpd.delay, msg->add_conn.dpd.action, my_vip, other_vip,
+                                       msg->add_conn.p2p.mediation, mediated_by_cfg, peer_id);
+               auth = peer_cfg->get_auth(peer_cfg);
+               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 (other_ca)
+               {
+                       DBG1(DBG_CFG, "  required other CA: %D", other_ca);
+                       certificate_t *cert = charon->credentials->get_cert(charon->credentials, 
+                                                                               CERT_X509, KEY_ANY, other_ca, TRUE);
+                       if (!cert)
+                       {
+                               DBG1(DBG_CFG, "deleted connection '%s': "
+                                                         "no trusted certificate found for required other CA",
+                                                          msg->add_conn.name);
+                               peer_cfg->destroy(peer_cfg);
+                               other_ca->destroy(other_ca);
+                               my_ts->destroy(my_ts);
+                               other_ts->destroy(other_ts);
+                               return;
+                       }
+                       /* require peer to authenticate against this cert */
+                       auth->add_item(auth, AUTHZ_CA_CERT, cert);
+                       cert->destroy(cert);
+                       other_ca->destroy(other_ca);
+               }
+               if (my_ca)
+               {
+                       certificate_t *cert = charon->credentials->get_cert(charon->credentials, 
+                                                                               CERT_X509, KEY_ANY, my_ca, TRUE);
+                       if (!cert)
+                       {
+                               DBG1(DBG_CFG, "deleted connection '%s': "
+                                                         "no trusted certificate found for my CA",
+                                                          msg->add_conn.name);
+                               peer_cfg->destroy(peer_cfg);
+                               my_ca->destroy(my_ca);
+                               my_ts->destroy(my_ts);
+                               other_ts->destroy(other_ts);
+                               return;
+                       }
+                       /* we authenticate against this cert */
+                       auth->add_item(auth, AUTHN_CA_CERT, cert);
+                       cert->destroy(cert);
+               }
+       }
+       child_cfg = child_cfg_create(
+                               msg->add_conn.name, msg->add_conn.rekey.ipsec_lifetime,
+                               msg->add_conn.rekey.ipsec_lifetime - msg->add_conn.rekey.margin,
+                               msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100, 
+                               msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
+                               msg->add_conn.mode);
+       
+       peer_cfg->add_child_cfg(peer_cfg, child_cfg);
+       
+       child_cfg->add_traffic_selector(child_cfg, TRUE, my_ts);
+       child_cfg->add_traffic_selector(child_cfg, FALSE, other_ts);
+       
+       if (msg->add_conn.algorithms.esp)
+       {
+               char *proposal_string;
+               char *strict = msg->add_conn.algorithms.esp + strlen(msg->add_conn.algorithms.esp) - 1;
+
+               if (*strict == '!')
+                       *strict = '\0';
+               else
+                       strict = NULL;
+               
+               while ((proposal_string = strsep(&msg->add_conn.algorithms.esp, ",")))
+               {
+                       proposal = proposal_create_from_string(PROTO_ESP, proposal_string);
+                       if (proposal == NULL)
+                       {
+                               DBG1(DBG_CFG, "invalid ESP proposal string: %s", proposal_string);
+                               peer_cfg->destroy(peer_cfg);
+                               return;
+                       }
+                       child_cfg->add_proposal(child_cfg, proposal);
+               }
+               if (!strict)
+               {
+                       proposal = proposal_create_default(PROTO_ESP);
+                       child_cfg->add_proposal(child_cfg, proposal);
+               }
+       }
+       else
+       {
+               proposal = proposal_create_default(PROTO_ESP);
+               child_cfg->add_proposal(child_cfg, proposal);
+       }
+       
+       if (!use_existing)
+       {
+               /* add config to backend */
+               this->configs.mutex->lock(this->configs.mutex);
+               this->configs.list->insert_last(this->configs.list, peer_cfg);
+               this->configs.mutex->unlock(this->configs.mutex);
+               DBG1(DBG_CFG, "added configuration '%s': %H[%D]...%H[%D]",
+                        msg->add_conn.name, my_host, my_id, other_host, other_id);
+       }
+       return;
+
+       /* mopping up after parsing errors */
+
+destroy_ids:
+       my_id->destroy(my_id);
+       other_id->destroy(other_id);
+       DESTROY_IF(mediated_by_cfg);
+       DESTROY_IF(peer_id);
+
+destroy_hosts:
+       my_host->destroy(my_host);
+       other_host->destroy(other_host);
+}
+
+/**
+ * Delete a connection from the list
+ */
+static void stroke_del_conn(private_stroke_t *this, stroke_msg_t *msg, FILE *out)
+{
+       enumerator_t *enumerator, *children;
+       peer_cfg_t *peer;
+       child_cfg_t *child;
+       
+       pop_string(msg, &(msg->del_conn.name));
+       DBG1(DBG_CFG, "received stroke: delete connection '%s'", msg->del_conn.name);
+       
+       this->configs.mutex->lock(this->configs.mutex);
+       enumerator = this->configs.list->create_enumerator(this->configs.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->configs.list->remove_at(this->configs.list, enumerator);
+                       peer->destroy(peer);
+                       continue;
+               }
+               /* 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);
+                               child->destroy(child);
+                       }
+               }
+               children->destroy(children);
+       }
+       enumerator->destroy(enumerator);
+       this->configs.mutex->unlock(this->configs.mutex);
+       
+       fprintf(out, "deleted connection '%s'\n", msg->del_conn.name);
+}
+
+/**
+ * get the child_cfg with the same name as the peer cfg
+ */
+static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
+{
+       child_cfg_t *current, *found = NULL;
+       enumerator_t *enumerator;
+       
+       enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+       while (enumerator->enumerate(enumerator, &current))
+       {
+               if (streq(current->get_name(current), name))
+               {
+                       found = current;
+                       found->get_ref(found);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
+/**
+ * logging to the stroke interface
+ */
+static bool stroke_log(stroke_log_info_t *info, signal_t signal, level_t level,
+                                          ike_sa_t *ike_sa, char *format, va_list args)
+{
+       if (level <= info->level)
+       {
+               if (vfprintf(info->out, format, args) < 0 ||
+                       fprintf(info->out, "\n") < 0 ||
+                       fflush(info->out) != 0)
+               {
+                       return FALSE;
+               }
+       }
+       return TRUE;
+}
+
+/**
+ * initiate a connection by name
+ */
+static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg, FILE *out)
+{
+       peer_cfg_t *peer_cfg;
+       child_cfg_t *child_cfg;
+       stroke_log_info_t info;
+       
+       pop_string(msg, &(msg->initiate.name));
+       DBG1(DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name);
+       
+       peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
+                                                                                                         msg->initiate.name);
+       if (peer_cfg == NULL)
+       {
+               fprintf(out, "no config named '%s'\n", msg->initiate.name);
+               return;
+       }
+       if (peer_cfg->get_ike_version(peer_cfg) != 2)
+       {
+               DBG1(DBG_CFG, "ignoring initiation request for IKEv%d config",
+                        peer_cfg->get_ike_version(peer_cfg));
+               peer_cfg->destroy(peer_cfg);
+               return;
+       }
+       
+       child_cfg = get_child_from_peer(peer_cfg, msg->initiate.name);
+       if (child_cfg == NULL)
+       {
+               fprintf(out, "no child config named '%s'\n", msg->initiate.name);
+               peer_cfg->destroy(peer_cfg);
+               return;
+       }
+       
+       if (msg->output_verbosity < 0)
+       {
+               charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+                                                                        NULL, NULL);
+       }
+       else
+       {
+               info.out = out;
+               info.level = msg->output_verbosity;
+               charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+                                                                        (controller_cb_t)stroke_log, &info);
+       }
+}
+
+/**
+ * route a policy (install SPD entries)
+ */
+static void stroke_route(private_stroke_t *this, stroke_msg_t *msg, FILE *out)
+{
+       peer_cfg_t *peer_cfg;
+       child_cfg_t *child_cfg;
+       stroke_log_info_t info;
+       
+       pop_string(msg, &(msg->route.name));
+       DBG1(DBG_CFG, "received stroke: route '%s'", msg->route.name);
+       
+       peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
+                                                                                                         msg->route.name);
+       if (peer_cfg == NULL)
+       {
+               fprintf(out, "no config named '%s'\n", msg->route.name);
+               return;
+       }
+       if (peer_cfg->get_ike_version(peer_cfg) != 2)
+       {
+               peer_cfg->destroy(peer_cfg);
+               return;
+       }
+       
+       child_cfg = get_child_from_peer(peer_cfg, msg->route.name);
+       if (child_cfg == NULL)
+       {
+               fprintf(out, "no child config named '%s'\n", msg->route.name);
+               peer_cfg->destroy(peer_cfg);
+               return;
+       }
+       
+       info.out = out;
+       info.level = msg->output_verbosity;
+       charon->controller->route(charon->controller, peer_cfg, child_cfg,
+                                                         (controller_cb_t)stroke_log, &info);
+       peer_cfg->destroy(peer_cfg);
+       child_cfg->destroy(child_cfg);
+}
+
+/**
+ * unroute a policy
+ */
+static void stroke_unroute(private_stroke_t *this, stroke_msg_t *msg, FILE *out)
+{
+       char *name;
+       ike_sa_t *ike_sa;
+       iterator_t *iterator;
+       stroke_log_info_t info;
+       
+       pop_string(msg, &(msg->terminate.name));
+       name = msg->terminate.name;
+       
+       info.out = out;
+       info.level = msg->output_verbosity;
+       
+       iterator = charon->controller->create_ike_sa_iterator(charon->controller);
+       while (iterator->iterate(iterator, (void**)&ike_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 (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);
+                               iterator->destroy(iterator);
+                               charon->controller->unroute(charon->controller, id,
+                                                               (controller_cb_t)stroke_log, &info);
+                               return;
+                       }
+               }
+               children->destroy(children);
+       }
+       iterator->destroy(iterator);
+       DBG1(DBG_CFG, "no such SA found");
+}
+
+/**
+ * terminate a connection by name
+ */
+static void stroke_terminate(private_stroke_t *this, stroke_msg_t *msg, FILE *out)
+{
+       char *string, *pos = NULL, *name = NULL;
+       u_int32_t id = 0;
+       bool child;
+       int len;
+       ike_sa_t *ike_sa;
+       iterator_t *iterator;
+       stroke_log_info_t info;
+       
+       pop_string(msg, &(msg->terminate.name));
+       string = msg->terminate.name;
+       DBG1(DBG_CFG, "received stroke: terminate '%s'", string);
+       
+       len = strlen(string);
+       if (len < 1)
+       {
+               DBG1(DBG_CFG, "error parsing string");
+               return;
+       }
+       switch (string[len-1])
+       {
+               case '}':
+                       child = TRUE;
+                       pos = strchr(string, '{');
+                       break;
+               case ']':
+                       child = FALSE;
+                       pos = strchr(string, '[');
+                       break;
+               default:
+                       name = string;
+                       child = FALSE;
+                       break;
+       }
+       
+       if (name)
+       {
+               /* is a single name */
+       }
+       else if (pos == string + len - 2)
+       {       /* is name[] or name{} */
+               string[len-2] = '\0';
+               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;
+               }
+       }
+       
+       info.out = out;
+       info.level = msg->output_verbosity;
+       
+       iterator = charon->controller->create_ike_sa_iterator(charon->controller);
+       while (iterator->iterate(iterator, (void**)&ike_sa))
+       {
+               child_sa_t *child_sa;
+               iterator_t *children;
+               
+               if (child)
+               {
+                       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)))
+                               {
+                                       id = child_sa->get_reqid(child_sa);
+                                       children->destroy(children);
+                                       iterator->destroy(iterator);
+                                       
+                                       charon->controller->terminate_child(charon->controller, id,
+                                                                       (controller_cb_t)stroke_log, &info);
+                                       return;
+                               }
+                       }
+                       children->destroy(children);
+               }
+               else if ((name && streq(name, ike_sa->get_name(ike_sa))) ||
+                                (id && id == ike_sa->get_unique_id(ike_sa)))
+               {
+                       id = ike_sa->get_unique_id(ike_sa);
+                       /* unlock manager first */
+                       iterator->destroy(iterator);
+                       
+                       charon->controller->terminate_ike(charon->controller, id,
+                                                                       (controller_cb_t)stroke_log, &info);
+                       return;
+               }
+               
+       }
+       iterator->destroy(iterator);
+       DBG1(DBG_CFG, "no such SA found");
+}
+
+/**
+ * Add a ca information record to the cainfo list
+ */
+static void stroke_add_ca(private_stroke_t *this,
+                                                 stroke_msg_t *msg, FILE *out)
+{
+       certificate_t *cert;
+       ca_section_t *ca;
+       
+       pop_string(msg, &msg->add_ca.name);
+       pop_string(msg, &msg->add_ca.cacert);
+       pop_string(msg, &msg->add_ca.crluri);
+       pop_string(msg, &msg->add_ca.crluri2);
+       pop_string(msg, &msg->add_ca.ocspuri);
+       pop_string(msg, &msg->add_ca.ocspuri2);
+       
+       DBG1(DBG_CFG, "received stroke: add ca '%s'", msg->add_ca.name);
+       
+       DBG2(DBG_CFG, "ca %s",        msg->add_ca.name);
+       DBG2(DBG_CFG, "  cacert=%s",  msg->add_ca.cacert);
+       DBG2(DBG_CFG, "  crluri=%s",  msg->add_ca.crluri);
+       DBG2(DBG_CFG, "  crluri2=%s", msg->add_ca.crluri2);
+       DBG2(DBG_CFG, "  ocspuri=%s", msg->add_ca.ocspuri);
+       DBG2(DBG_CFG, "  ocspuri2=%s", msg->add_ca.ocspuri2);
+
+       if (msg->add_ca.cacert == NULL)
+       {
+               DBG1(DBG_CFG, "missing cacert parameter");
+               return;
+       }
+
+       cert = load_ca_cert(this, msg->add_ca.cacert);
+       if (cert)
+       {
+               ca = ca_section_create(msg->add_ca.name, cert);
+               if (msg->add_ca.crluri)
+               {
+                       ca->crl->insert_last(ca->crl, strdup(msg->add_ca.crluri));
+               }
+               if (msg->add_ca.crluri2)
+               {
+                       ca->crl->insert_last(ca->crl, strdup(msg->add_ca.crluri2));
+               }
+               if (msg->add_ca.ocspuri)
+               {
+                       ca->ocsp->insert_last(ca->ocsp, strdup(msg->add_ca.ocspuri));
+               }
+               if (msg->add_ca.ocspuri2)
+               {
+                       ca->ocsp->insert_last(ca->ocsp, strdup(msg->add_ca.ocspuri2));
+               }
+               this->ca_creds.mutex->lock(this->ca_creds.mutex);
+               this->ca_creds.sections->insert_last(this->ca_creds.sections, ca);
+               this->ca_creds.mutex->unlock(this->ca_creds.mutex);
+               DBG1(DBG_CFG, "added ca '%s'", msg->add_ca.name);
+       }
+}
+
+/**
+ * Delete a ca information record from the cainfo list
+ */
+static void stroke_del_ca(private_stroke_t *this,
+                                                 stroke_msg_t *msg, FILE *out)
+{
+       enumerator_t *enumerator;
+       ca_section_t *ca = NULL;
+       
+       pop_string(msg, &(msg->del_ca.name));
+       DBG1(DBG_CFG, "received stroke: delete ca '%s'", msg->del_ca.name);
+       
+       this->ca_creds.mutex->lock(this->ca_creds.mutex);
+       enumerator = this->ca_creds.sections->create_enumerator(this->ca_creds.sections);
+       while (enumerator->enumerate(enumerator, &ca))
+       {
+               if (streq(ca->name, msg->del_ca.name))
+               {
+                       this->ca_creds.sections->remove_at(this->ca_creds.sections, enumerator);
+                       break;
+               }
+               ca = NULL;
+       }
+       enumerator->destroy(enumerator);
+       this->ca_creds.mutex->unlock(this->ca_creds.mutex);
+       if (ca == NULL)
+       {
+               fprintf(out, "no ca named '%s' found\n", msg->del_ca.name);
+               return;
+       }
+       ca_section_destroy(ca);
+       /* TODO: flush cached certs */
+}
+
+/**
+ * log an IKE_SA to out
+ */
+static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
+{
+       ike_sa_id_t *id = ike_sa->get_id(ike_sa);
+       u_int32_t rekey, reauth;
+
+       fprintf(out, "%12s[%d]: %N, %H[%D]...%H[%D]\n",
+                       ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
+                       ike_sa_state_names, ike_sa->get_state(ike_sa),
+                       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));
+       
+       if (all)
+       {
+               fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_r%s",
+                               ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
+                               id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "",
+                               id->get_responder_spi(id), id->is_initiator(id) ? "" : "*");
+       
+               rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY_TIME);
+               reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH_TIME);
+               if (rekey)
+               {
+                       fprintf(out, ", rekeying in %V", &rekey);
+               }
+               if (reauth)
+               {
+                       fprintf(out, ", reauthentication in %V", &reauth);
+               }
+               if (!rekey && !reauth)
+               {
+                       fprintf(out, ", rekeying disabled");
+               }
+               fprintf(out, "\n");
+       }
+}
+
+/**
+ * log an CHILD_SA to out
+ */
+static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
+{
+       u_int32_t rekey, now = time(NULL);
+       u_int32_t use_in, use_out, use_fwd;
+       encryption_algorithm_t encr_alg;
+       integrity_algorithm_t int_alg;
+       size_t encr_len, int_len;
+       mode_t mode;
+       
+       child_sa->get_stats(child_sa, &mode, &encr_alg, &encr_len,
+                                               &int_alg, &int_len, &rekey, &use_in, &use_out,
+                                               &use_fwd);
+       
+       fprintf(out, "%12s{%d}:  %N, %N", 
+                       child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+                       child_sa_state_names, child_sa->get_state(child_sa),
+                       mode_names, mode);
+       
+       if (child_sa->get_state(child_sa) == CHILD_INSTALLED)
+       {
+               fprintf(out, ", %N SPIs: %.8x_i %.8x_o",
+                               protocol_id_names, child_sa->get_protocol(child_sa),
+                               htonl(child_sa->get_spi(child_sa, TRUE)),
+                               htonl(child_sa->get_spi(child_sa, FALSE)));
+               
+               if (all)
+               {
+                       fprintf(out, "\n%12s{%d}:  ", child_sa->get_name(child_sa), 
+                                       child_sa->get_reqid(child_sa));
+                       
+                       
+                       if (child_sa->get_protocol(child_sa) == PROTO_ESP)
+                       {
+                               fprintf(out, "%N", encryption_algorithm_names, encr_alg);
+                               
+                               if (encr_len)
+                               {
+                                       fprintf(out, "-%d", encr_len);
+                               }
+                               fprintf(out, "/");
+                       }
+                       
+                       fprintf(out, "%N", integrity_algorithm_names, int_alg);
+                       if (int_len)
+                       {
+                               fprintf(out, "-%d", int_len);
+                       }
+                       fprintf(out, ", rekeying ");
+                       
+                       if (rekey)
+                       {
+                               fprintf(out, "in %#V", &now, &rekey);
+                       }
+                       else
+                       {
+                               fprintf(out, "disabled");
+                       }
+                       
+                       fprintf(out, ", last use: ");
+                       use_in = max(use_in, use_fwd);
+                       if (use_in)
+                       {
+                               fprintf(out, "%ds_i ", now - use_in);
+                       }
+                       else
+                       {
+                               fprintf(out, "no_i ");
+                       }
+                       if (use_out)
+                       {
+                               fprintf(out, "%ds_o ", now - use_out);
+                       }
+                       else
+                       {
+                               fprintf(out, "no_o ");
+                       }
+               }
+       }
+       
+       fprintf(out, "\n%12s{%d}:   %#R=== %#R\n",
+                       child_sa->get_name(child_sa), child_sa->get_reqid(child_sa),
+                       child_sa->get_traffic_selectors(child_sa, TRUE),
+                       child_sa->get_traffic_selectors(child_sa, FALSE));
+}
+
+/**
+ * show status of daemon
+ */
+static void stroke_status(private_stroke_t *this, stroke_msg_t *msg, FILE *out,
+                                                 bool all)
+{
+       enumerator_t *enumerator, *children;
+       iterator_t *iterator;
+       host_t *host;
+       peer_cfg_t *peer_cfg;
+       ike_cfg_t *ike_cfg;
+       child_cfg_t *child_cfg;
+       ike_sa_t *ike_sa;
+       char *name = NULL;
+       
+       if (msg->status.name)
+       {
+               pop_string(msg, &(msg->status.name));
+               name = msg->status.name;
+       }
+       
+       if (all)
+       {
+               fprintf(out, "Performance:\n");
+               fprintf(out, "  worker threads: %d idle of %d,",
+                               charon->processor->get_idle_threads(charon->processor),
+                               charon->processor->get_total_threads(charon->processor));
+               fprintf(out, " job queue load: %d,",
+                               charon->processor->get_job_load(charon->processor));
+               fprintf(out, " scheduled events: %d\n",
+                               charon->scheduler->get_job_load(charon->scheduler));
+               iterator = charon->kernel_interface->create_address_iterator(
+                                                                                                       charon->kernel_interface);
+               fprintf(out, "Listening IP addresses:\n");
+               while (iterator->iterate(iterator, (void**)&host))
+               {
+                       fprintf(out, "  %H\n", host);
+               }
+               iterator->destroy(iterator);
+       
+               fprintf(out, "Connections:\n");
+               enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
+               while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
+               {
+                       if (peer_cfg->get_ike_version(peer_cfg) != 2 ||
+                               (name && !streq(name, peer_cfg->get_name(peer_cfg))))
+                       {
+                               continue;
+                       }
+                       
+                       ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
+                       fprintf(out, "%12s:  %H[%D]...%H[%D]\n", peer_cfg->get_name(peer_cfg),
+                                       ike_cfg->get_my_host(ike_cfg), peer_cfg->get_my_id(peer_cfg),
+                                       ike_cfg->get_other_host(ike_cfg), peer_cfg->get_other_id(peer_cfg));
+                       /* TODO: list CAs and groups */
+                       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\n", 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));
+                       }
+                       children->destroy(children);
+               }
+               enumerator->destroy(enumerator);
+       }
+       
+       iterator = charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
+       if (all && iterator->get_count(iterator) > 0)
+       {
+               fprintf(out, "Security Associations:\n");
+       }
+       while (iterator->iterate(iterator, (void**)&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)))
+               {
+                       log_ike_sa(out, ike_sa, all);
+                       ike_printed = TRUE;
+               }
+
+               while (children->iterate(children, (void**)&child_sa))
+               {
+                       if (name == NULL || streq(name, child_sa->get_name(child_sa)))
+                       {
+                               if (!ike_printed)
+                               {
+                                       log_ike_sa(out, ike_sa, all);
+                                       ike_printed = TRUE;
+                               }
+                               log_child_sa(out, child_sa, all);
+                       }       
+               }
+               children->destroy(children);
+       }
+       iterator->destroy(iterator);
+}
+
+/**
+ * list all X.509 certificates matching the flags
+ */
+static void stroke_list_certs(char *label, x509_flag_t flags, bool utc, FILE *out)
+{
+       bool first = TRUE;
+       time_t now = time(NULL);
+       certificate_t *cert;
+       enumerator_t *enumerator;
+       
+       enumerator = charon->credentials->create_cert_enumerator(
+                                               charon->credentials, CERT_X509, KEY_ANY, NULL, FALSE);
+       while (enumerator->enumerate(enumerator, (void**)&cert))
+       {
+               x509_t *x509 = (x509_t*)cert;
+               x509_flag_t x509_flags = x509->get_flags(x509);
+
+               if (x509_flags & flags)
+               {
+                       enumerator_t *enumerator;
+                       identification_t *altName;
+                       bool first_altName = TRUE;
+                       chunk_t serial = x509->get_serial(x509);
+                       identification_t *authkey = x509->get_authKeyIdentifier(x509);
+                       time_t notBefore, notAfter;
+                       public_key_t *public = cert->get_public_key(cert);
+
+                       if (first)
+                       {
+                               fprintf(out, "\n");
+                               fprintf(out, "List of %s:\n", label);
+                               first = FALSE;
+                       }
+                       fprintf(out, "\n");
+
+                       /* list subjectAltNames */
+                       enumerator = x509->create_subjectAltName_enumerator(x509);
+                       while (enumerator->enumerate(enumerator, (void**)&altName))
+                       {
+                               if (first_altName)
+                               {
+                                       fprintf(out, "  altNames:  ");
+                                       first_altName = FALSE;
+                               }
+                               else
+                               {
+                                       fprintf(out, ", ");
+                               }
+                               fprintf(out, "%D", altName);
+                       }
+                       if (!first_altName)
+                       {
+                               fprintf(out, "\n");
+                       }
+                       enumerator->destroy(enumerator);
+
+                       fprintf(out, "  subject:  %D\n", cert->get_subject(cert));
+                       fprintf(out, "  issuer:   %D\n", cert->get_issuer(cert));
+                       fprintf(out, "  serial:    %#B\n", &serial);
+
+                       /* list validity */
+                       cert->get_validity(cert, &now, &notBefore, &notAfter);
+                       fprintf(out, "  validity:  not before %#T, ", &notBefore, utc);
+                       if (now < notBefore)
+                       {
+                               fprintf(out, "not valid yet (valid in %#V)\n", &now, &notBefore);
+                       }
+                       else
+                       {
+                               fprintf(out, "ok\n");
+                       }
+                       fprintf(out, "             not after  %#T, ", &notAfter, utc);
+                       if (now > notAfter)
+                       {
+                               fprintf(out, "expired (%#V ago)\n", &now, &notAfter);
+                       }
+                       else
+                       {
+                               fprintf(out, "ok");
+                               if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
+                               {
+                                       fprintf(out, " (expires in %#V)", &now, &notAfter);
+                               }
+                               fprintf(out, " \n");
+                       }
+       
+                       /* list public key information */
+                       if (public)
+                       {
+                               private_key_t *private = NULL;
+                               identification_t *id, *keyid;
+                       
+                               id    = public->get_id(public, ID_PUBKEY_SHA1);
+                               keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
+
+                               if (flags & X509_PEER)
+                               {
+                                       private = charon->credentials->get_private(
+                                                                       charon->credentials, 
+                                                                       public->get_type(public), id, NULL);
+                               }
+                               fprintf(out, "  pubkey:    %N %d bits%s\n",
+                                               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);
+                               DESTROY_IF(private);
+                               public->destroy(public);
+                       }
+       
+                       /* list optional authorityKeyIdentifier */
+                       if (authkey)
+                       {
+                               fprintf(out, "  authkey:   %D\n", authkey);
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+}
+
+/**
+ * list all X.509 CRLs
+ */
+static void stroke_list_crls(bool utc, FILE *out)
+{
+       bool first = TRUE;
+       time_t thisUpdate, nextUpdate, now = time(NULL);
+       certificate_t *cert;
+       enumerator_t *enumerator;
+       
+       enumerator = charon->credentials->create_cert_enumerator(
+                                               charon->credentials, CERT_X509_CRL, KEY_ANY, NULL, FALSE);
+       while (enumerator->enumerate(enumerator, (void**)&cert))
+       {
+               crl_t *crl = (crl_t*)cert;
+               chunk_t serial  = crl->get_serial(crl);
+               identification_t *authkey = crl->get_authKeyIdentifier(crl);
+
+               if (first)
+               {
+                       fprintf(out, "\n");
+                       fprintf(out, "List of X.509 CRLs:\n");
+                       first = FALSE;
+               }
+               fprintf(out, "\n");
+
+               fprintf(out, "  issuer:   %D\n", cert->get_issuer(cert));
+
+               /* list optional crlNumber */
+               if (serial.ptr)
+               {
+                       fprintf(out, "  serial:    %#B\n", &serial);
+               }
+
+               /* count the number of revoked certificates */
+               {
+                       int count = 0;
+                       enumerator_t *enumerator = crl->create_enumerator(crl);
+
+                       while (enumerator->enumerate(enumerator, NULL, NULL, NULL))
+                       {
+                               count++;
+                       }
+                       fprintf(out, "  revoked:   %d certificate%s\n", count,
+                                                       (count == 1)? "" : "s");
+                       enumerator->destroy(enumerator);
+               }
+
+               /* list validity */
+               cert->get_validity(cert, &now, &thisUpdate, &nextUpdate);
+               fprintf(out, "  updates:   this %#T\n",  &thisUpdate, utc);
+               fprintf(out, "             next %#T, ", &nextUpdate, utc);
+               if (now > nextUpdate)
+               {
+                       fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
+               }
+               else
+               {
+                       fprintf(out, "ok");
+                       if (now > nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
+                       {
+                               fprintf(out, " (expires in %#V)", &now, &nextUpdate);
+                       }
+                       fprintf(out, " \n");
+               }
+
+               /* list optional authorityKeyIdentifier */
+               if (authkey)
+               {
+                       fprintf(out, "  authkey:   %D\n", authkey);
+               }
+       }
+       enumerator->destroy(enumerator);
+}
+
+/**
+ * list all CA information sections
+ */
+static void stroke_list_cainfos(private_stroke_t *this, FILE *out)
+{
+       bool first = TRUE;
+       ca_section_t *section;
+       enumerator_t *enumerator;
+       
+       this->ca_creds.mutex->lock(this->ca_creds.mutex);
+       enumerator = this->ca_creds.sections->create_enumerator(this->ca_creds.sections);
+       while (enumerator->enumerate(enumerator, (void**)&section))
+       {
+               certificate_t *cert = section->cert;
+               public_key_t *public = cert->get_public_key(cert);
+
+               if (first)
+               {
+                       fprintf(out, "\n");
+                       fprintf(out, "List of CA Information Sections:\n");
+                       first = FALSE;
+               }
+               fprintf(out, "\n");
+               fprintf(out, "  authname: %D\n", cert->get_subject(cert));
+
+               /* list authkey and keyid */
+               if (public)
+               {
+                       fprintf(out, "  authkey:   %D\n",
+                                       public->get_id(public, ID_PUBKEY_SHA1));
+                       fprintf(out, "  keyid:     %D\n",
+                                       public->get_id(public, ID_PUBKEY_INFO_SHA1));
+                       public->destroy(public);
+               }
+               
+               /* list CRL URIs */
+               {
+                       bool first = TRUE;
+                       char *crluri;
+                       enumerator_t *enumerator;
+
+                       enumerator = section->crl->create_enumerator(section->crl);
+                       while (enumerator->enumerate(enumerator, (void**)&crluri))
+                       {
+                               if (first)
+                               {
+                                       fprintf(out, "  crluris:  ");
+                                       first = FALSE;
+                               }
+                               else
+                               {
+                                       fprintf(out, "            ");
+                               }
+                               fprintf(out, "'%s'\n", crluri);
+                       }
+                       enumerator->destroy(enumerator);
+               }
+
+               /* list OCSP URIs */
+               {
+                       bool first = TRUE;
+                       char *ocspuri;
+                       enumerator_t *enumerator;
+
+                       enumerator = section->ocsp->create_enumerator(section->ocsp);
+                       while (enumerator->enumerate(enumerator, (void**)&ocspuri))
+                       {
+                               if (first)
+                               {
+                                       fprintf(out, "  ocspuris: ");
+                                       first = FALSE;
+                               }
+                               else
+                               {
+                                       fprintf(out, "            ");
+                               }
+                               fprintf(out, "'%s'\n", ocspuri);
+                       }
+                       enumerator->destroy(enumerator);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->ca_creds.mutex->unlock(this->ca_creds.mutex);
+}
+
+/**
+ * list various information
+ */
+static void stroke_list(private_stroke_t *this, stroke_msg_t *msg, FILE *out)
+{
+       if (msg->list.flags & LIST_CERTS)
+       {
+               stroke_list_certs("X.509 End Entity Certificates",
+                                                  X509_PEER, msg->list.utc, out);
+       }
+       if (msg->list.flags & LIST_CACERTS)
+       {
+               stroke_list_certs("X.509 CA Certificates",
+                                                  X509_CA, msg->list.utc, out);
+       }
+       if (msg->list.flags & LIST_OCSPCERTS)
+       {
+               stroke_list_certs("X.509 OCSP Signer Certificates",
+                                                  X509_OCSP_SIGNER, msg->list.utc, out);
+       }
+       if (msg->list.flags & LIST_AACERTS)
+       {
+               stroke_list_certs("X.509 AA Certificates",
+                                                  X509_AA, msg->list.utc, out);
+       }
+       if (msg->list.flags & LIST_ACERTS)
+       {
+
+       }
+       if (msg->list.flags & LIST_CAINFOS)
+       {
+               stroke_list_cainfos(this, out);
+       }
+       if (msg->list.flags & LIST_CRLS)
+       {
+               stroke_list_crls(msg->list.utc, out);
+       }
+       if (msg->list.flags & LIST_OCSP)
+       {
+
+       }
+}
+
+/**
+ * reread various information
+ */
+static void stroke_reread(private_stroke_t *this,
+                                                 stroke_msg_t *msg, FILE *out)
+{
+       if (msg->reread.flags & REREAD_SECRETS)
+       {
+               DBG1(DBG_CFG, "rereading secrets");
+               load_secrets(this);
+       }
+       if (msg->reread.flags & REREAD_CACERTS)
+       {
+               DBG1(DBG_CFG, "rereading CA certificates from '%s'",
+                        CA_CERTIFICATE_DIR);
+               load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
+       }
+       if (msg->reread.flags & REREAD_OCSPCERTS)
+       {
+               DBG1(DBG_CFG, "rereading OCSP signer certificates from '%s'",
+                        OCSP_CERTIFICATE_DIR);
+               load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509,
+                        X509_OCSP_SIGNER);
+       }
+       if (msg->reread.flags & REREAD_AACERTS)
+       {
+               DBG1(DBG_CFG, "rereading AA certificates from '%s'",
+                        AA_CERTIFICATE_DIR);
+               load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
+       }
+       if (msg->reread.flags & REREAD_ACERTS)
+       {
+               DBG1(DBG_CFG, "rereading attribute certificates from '%s'",
+                        ATTR_CERTIFICATE_DIR);
+               load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
+       }
+       if (msg->reread.flags & REREAD_CRLS)
+       {
+               DBG1(DBG_CFG, "rereading CRLs from '%s'",
+                        CRL_DIR);
+               load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
+       }
+}
+
+/**
+ * purge various information
+ */
+static void stroke_purge(private_stroke_t *this, stroke_msg_t *msg, FILE *out)
+{
+       /* TODO: flush cache */
+}
+
+signal_t get_signal_from_logtype(char *type)
+{
+       if      (strcasecmp(type, "any") == 0) return SIG_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;
+       else return -1;
+}
+
+/**
+ * set the verbosity debug output
+ */
+static void stroke_loglevel(private_stroke_t *this, stroke_msg_t *msg, FILE *out)
+{
+       signal_t signal;
+       
+       pop_string(msg, &(msg->loglevel.type));
+       DBG1(DBG_CFG, "received stroke: loglevel %d for %s",
+                msg->loglevel.level, msg->loglevel.type);
+       
+       signal = get_signal_from_logtype(msg->loglevel.type);
+       if (signal < 0)
+       {
+               fprintf(out, "invalid type (%s)!\n", msg->loglevel.type);
+               return;
+       }
+       
+       charon->outlog->set_level(charon->outlog, signal, msg->loglevel.level);
+       charon->syslog->set_level(charon->syslog, signal, msg->loglevel.level);
+}
+
+typedef struct stroke_job_context_t stroke_job_context_t;
+
+/** job context to pass to processing thread */
+struct stroke_job_context_t {
+
+       /** file descriptor to read from */
+       int fd;
+       
+       /** global stroke interface */
+       private_stroke_t *this;
+};
+
+/**
+ * destroy a job context
+ */
+static void stroke_job_context_destroy(stroke_job_context_t *this)
+{
+       close(this->fd);
+       free(this);
+}
+
+/**
+ * process a stroke request from the socket pointed by "fd"
+ */
+static job_requeue_t stroke_process(stroke_job_context_t *ctx)
+{
+       stroke_msg_t *msg;
+       u_int16_t msg_length;
+       ssize_t bytes_read;
+       FILE *out;
+       private_stroke_t *this = ctx->this;
+       int strokefd = ctx->fd;
+       
+       /* peek the length */
+       bytes_read = recv(strokefd, &msg_length, sizeof(msg_length), MSG_PEEK);
+       if (bytes_read != sizeof(msg_length))
+       {
+               DBG1(DBG_CFG, "reading length of stroke message failed: %s",
+                        strerror(errno));
+               close(strokefd);
+               return JOB_REQUEUE_NONE;
+       }
+       
+       /* read message */
+       msg = malloc(msg_length);
+       bytes_read = recv(strokefd, msg, msg_length, 0);
+       if (bytes_read != msg_length)
+       {
+               DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno));
+               close(strokefd);
+               return JOB_REQUEUE_NONE;
+       }
+       
+       out = fdopen(strokefd, "w");
+       if (out == NULL)
+       {
+               DBG1(DBG_CFG, "opening stroke output channel failed: %s", strerror(errno));
+               close(strokefd);
+               free(msg);
+               return JOB_REQUEUE_NONE;
+       }
+       
+       DBG3(DBG_CFG, "stroke message %b", (void*)msg, msg_length);
+       
+       /* the stroke_* functions are blocking, as they listen on the bus. Add
+        * cancellation handlers. */
+       pthread_cleanup_push((void*)fclose, out);
+       pthread_cleanup_push(free, msg);
+       
+       switch (msg->type)
+       {
+               case STR_INITIATE:
+                       stroke_initiate(this, msg, out);
+                       break;
+               case STR_ROUTE:
+                       stroke_route(this, msg, out);
+                       break;
+               case STR_UNROUTE:
+                       stroke_unroute(this, msg, out);
+                       break;
+               case STR_TERMINATE:
+                       stroke_terminate(this, msg, out);
+                       break;
+               case STR_STATUS:
+                       stroke_status(this, msg, out, FALSE);
+                       break;
+               case STR_STATUS_ALL:
+                       stroke_status(this, msg, out, TRUE);
+                       break;
+               case STR_ADD_CONN:
+                       stroke_add_conn(this, msg, out);
+                       break;
+               case STR_DEL_CONN:
+                       stroke_del_conn(this, msg, out);
+                       break;
+               case STR_ADD_CA:
+                       stroke_add_ca(this, msg, out);
+                       break;
+               case STR_DEL_CA:
+                       stroke_del_ca(this, msg, out);
+                       break;
+               case STR_LOGLEVEL:
+                       stroke_loglevel(this, msg, out);
+                       break;
+               case STR_LIST:
+                       stroke_list(this, msg, out);
+                       break;
+               case STR_REREAD:
+                       stroke_reread(this, msg, out);
+                       break;
+               case STR_PURGE:
+                       stroke_purge(this, msg, out);
+                       break;
+               default:
+                       DBG1(DBG_CFG, "received unknown stroke");
+       }
+       /* remove and execute cancellation handlers */
+       pthread_cleanup_pop(1);
+       pthread_cleanup_pop(1);
+       
+       return JOB_REQUEUE_NONE;
+}
+
+/**
+ * Implementation of private_stroke_t.stroke_receive.
+ */
+static job_requeue_t stroke_receive(private_stroke_t *this)
+{
+       struct sockaddr_un strokeaddr;
+       int strokeaddrlen = sizeof(strokeaddr);
+       int strokefd;
+       int oldstate;
+       callback_job_t *job;
+       stroke_job_context_t *ctx;
+       
+       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+       strokefd = accept(this->socket, (struct sockaddr *)&strokeaddr, &strokeaddrlen);
+       pthread_setcancelstate(oldstate, NULL);
+       
+       if (strokefd < 0)
+       {
+               DBG1(DBG_CFG, "accepting stroke connection failed: %s", strerror(errno));
+               return JOB_REQUEUE_FAIR;
+       }
+       
+       ctx = malloc_thing(stroke_job_context_t);
+       ctx->fd = strokefd;
+       ctx->this = this;
+       job = callback_job_create((callback_job_cb_t)stroke_process,
+                                                         ctx, (void*)stroke_job_context_destroy, this->job);
+       charon->processor->queue_job(charon->processor, (job_t*)job);
+       
+       return JOB_REQUEUE_FAIR;
+}
+
+/**
+ * Implementation of interface_t.destroy.
+ */
+static void destroy(private_stroke_t *this)
+{
+       this->job->cancel(this->job);
+       charon->credentials->remove_set(charon->credentials, &this->ca_creds.set);
+       charon->credentials->remove_set(charon->credentials, &this->creds.set);
+       charon->backends->remove_backend(charon->backends, &this->configs.backend);
+       this->ca_creds.sections->destroy_function(this->ca_creds.sections, (void*)ca_section_destroy);
+       this->ca_creds.mutex->destroy(this->ca_creds.mutex);
+       this->creds.certs->destroy_offset(this->creds.certs, offsetof(certificate_t, destroy));
+       this->creds.shared->destroy_offset(this->creds.shared, offsetof(shared_key_t, destroy));
+       this->creds.private->destroy_offset(this->creds.private, offsetof(private_key_t, destroy));
+       this->creds.mutex->destroy(this->creds.mutex);
+       this->configs.list->destroy_offset(this->configs.list, offsetof(peer_cfg_t, destroy));
+       this->configs.mutex->destroy(this->configs.mutex);
+       free(this);
+}
+
+/**
+ * initialize and open stroke socket
+ */
+static bool open_socket(private_stroke_t *this)
+{
+       struct sockaddr_un socket_addr = { AF_UNIX, STROKE_SOCKET};
+       mode_t old;
+       
+       /* set up unix socket */
+       this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (this->socket == -1)
+       {
+               DBG1(DBG_CFG, "could not create stroke socket");
+               return FALSE;
+       }
+       
+       unlink(socket_addr.sun_path);
+       old = umask(~(S_IRWXU | S_IRWXG));
+       if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
+       {
+               DBG1(DBG_CFG, "could not bind stroke socket: %s", strerror(errno));
+               close(this->socket);
+               return FALSE;
+       }
+       umask(old);
+       if (chown(socket_addr.sun_path, IPSEC_UID, IPSEC_GID) != 0)
+       {
+               DBG1(DBG_CFG, "changing stroke socket permissions failed: %s",
+                        strerror(errno));
+       }
+       
+       if (listen(this->socket, 0) < 0)
+       {
+               DBG1(DBG_CFG, "could not listen on stroke socket: %s", strerror(errno));
+               close(this->socket);
+               unlink(socket_addr.sun_path);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/**
+ * load all certificates from ipsec.d
+ */
+static void load_certs(private_stroke_t *this)
+{
+       DBG1(DBG_CFG, "loading CA certificates from '%s'",
+                CA_CERTIFICATE_DIR);
+       load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA);
+
+       DBG1(DBG_CFG, "loading AA certificates from '%s'",
+                AA_CERTIFICATE_DIR);
+       load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA);
+
+       DBG1(DBG_CFG, "loading OCSP signer certificates from '%s'",
+                OCSP_CERTIFICATE_DIR);
+       load_certdir(this, OCSP_CERTIFICATE_DIR, CERT_X509, X509_OCSP_SIGNER);
+
+       DBG1(DBG_CFG, "loading attribute certificates from '%s'",
+                ATTR_CERTIFICATE_DIR);
+       load_certdir(this, ATTR_CERTIFICATE_DIR, CERT_X509_AC, 0);
+
+       DBG1(DBG_CFG, "loading CRLs from '%s'",
+                CRL_DIR);
+       load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
+}
+
+/*
+ * Described in header-file
+ */
+plugin_t *plugin_create()
+{
+       private_stroke_t *this = malloc_thing(private_stroke_t);
+
+       /* public functions */
+       this->public.plugin.destroy = (void (*)(plugin_t*))destroy;
+       
+       if (!open_socket(this))
+       {
+               free(this);
+               return NULL;
+       }
+       
+       this->ca_creds.sections = linked_list_create();
+       this->ca_creds.mutex = mutex_create(MUTEX_RECURSIVE);
+       this->creds.certs = linked_list_create();
+       this->creds.shared = linked_list_create();
+       this->creds.private = linked_list_create();
+       this->creds.mutex = mutex_create(MUTEX_RECURSIVE);
+       this->configs.list = linked_list_create();
+       this->configs.mutex = mutex_create(MUTEX_RECURSIVE);
+       
+       this->ca_creds.set.create_private_enumerator = (void*)return_null;
+       this->ca_creds.set.create_cert_enumerator = (void*)return_null;
+       this->ca_creds.set.create_shared_enumerator = (void*)return_null;
+       this->ca_creds.set.create_cdp_enumerator = (void*)create_cdp_enumerator;
+       charon->credentials->add_set(charon->credentials, &this->ca_creds.set);
+       
+       this->creds.set.create_private_enumerator = (void*)create_private_enumerator;
+       this->creds.set.create_cert_enumerator = (void*)create_cert_enumerator;
+       this->creds.set.create_shared_enumerator = (void*)create_shared_enumerator;
+       this->creds.set.create_cdp_enumerator = (void*)return_null;
+       charon->credentials->add_set(charon->credentials, &this->creds.set);
+
+       load_certs(this);
+       load_secrets(this);
+       
+       this->configs.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
+       this->configs.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
+       this->configs.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
+       charon->backends->add_backend(charon->backends, &this->configs.backend);
+       
+       this->job = callback_job_create((callback_job_cb_t)stroke_receive,
+                                                                       this, NULL, NULL);
+       charon->processor->queue_job(charon->processor, (job_t*)this->job);
+       
+       return &this->public.plugin;
+}
+
similarity index 52%
rename from src/charon/control/interfaces/stroke_interface.h
rename to src/charon/plugins/stroke/stroke.h
index f1b68023a49b428cf3a6f574c4d07acad9b78f86..b61f4109d0e83fb9325a8afb6395cb2ef887ae90 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file stroke_interface.h
- *
- * @brief Interface of stroke_t.
- *
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 STROKE_INTERFACE_H_
-#define STROKE_INTERFACE_H_
+/**
+ * @defgroup stroke stroke
+ * @ingroup cplugins
+ *
+ * @defgroup stroke_i stroke
+ * @{ @ingroup stroke
+ */
+#ifndef STROKE_H_
+#define STROKE_H_
 
-typedef struct stroke_interface_t stroke_interface_t;
+#include <plugins/plugin.h>
 
-#include <control/interfaces/interface.h>
+typedef struct stroke_t stroke_t;
 
 /**
- * @brief Simple configuration interface using unix-sockets.
- * 
+ * strongSwan 2.x style configuration and control interface.
+ *
  * Stroke is a home-brewed communication interface inspired by whack. It
  * uses a unix socket (/var/run/charon.ctl).
- * 
- * @b Constructors:
- * - stroke_create()
- * 
- * @ingroup interfaces
  */
-struct stroke_interface_t {
-       
+struct stroke_t {
+
        /**
-        * implements interface_t.
+        * implements plugin interface
         */
-       interface_t interface;
+       plugin_t plugin;
 };
 
-
 /**
- * @brief Create the stroke interface and listen on the socket.
- * 
- * @return                     interface_t for the stroke interface
- * 
- * @ingroup interfaces
+ * Instanciate stroke plugin.
  */
-interface_t *interface_create(void);
-
-#endif /* STROKE_INTERFACE_H_ */
+plugin_t *plugin_create();
 
+#endif /* STROKE_H_ @}*/
diff --git a/src/charon/plugins/unit_tester/Makefile.am b/src/charon/plugins/unit_tester/Makefile.am
new file mode 100644 (file)
index 0000000..fb52443
--- /dev/null
@@ -0,0 +1,17 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libcharon-unit-tester.la
+
+libcharon_unit_tester_la_SOURCES = unit_tester.c unit_tester.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 \
+  tests/test_mutex.c
+libcharon_unit_tester_la_LDFLAGS = -module
+
diff --git a/src/charon/plugins/unit_tester/tests.h b/src/charon/plugins/unit_tester/tests.h
new file mode 100644 (file)
index 0000000..5def0b0
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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$
+ */
+
+/**
+ * @defgroup tests tests 
+ * @{ @ingroup unit_tester
+ */
+
+DEFINE_TEST("linked_list_t->remove()", test_list_remove, FALSE)
+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("auth info", test_auth_info, FALSE)
+DEFINE_TEST("FIPS PRF", fips_prf_test, FALSE)
+DEFINE_TEST("CURL get", test_curl_get, FALSE)
+DEFINE_TEST("MySQL operations", test_mysql, FALSE)
+DEFINE_TEST("SQLite operations", test_sqlite, FALSE)
+DEFINE_TEST("mutex primitive", test_mutex, 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
new file mode 100644 (file)
index 0000000..2640c95
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <daemon.h>
+#include <library.h>
+#include <credentials/auth_info.h>
+
+
+char buf[] = {0x01,0x02,0x03,0x04};
+chunk_t chunk = chunk_from_buf(buf);
+char certbuf[] = {
+       0x30,0x82,0x02,0xfa,0x30,0x82,0x01,0xe2,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x5a,
+       0xf2,0x65,0xae,0x78,0xff,0x23,0xde,0xf7,0xa6,0xa3,0x94,0x8c,0x3f,0xa0,0xc1,0x30,
+       0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x39,
+       0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30,
+       0x17,0x06,0x03,0x55,0x04,0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74,
+       0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,
+       0x03,0x13,0x06,0x6d,0x61,0x72,0x74,0x69,0x6e,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,
+       0x34,0x32,0x37,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x17,0x0d,0x31,0x32,0x30,0x34,
+       0x32,0x35,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x30,0x39,0x31,0x0b,0x30,0x09,0x06,
+       0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,
+       0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53,
+       0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x6d,0x61,
+       0x72,0x74,0x69,0x6e,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,
+       0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,
+       0x02,0x82,0x01,0x01,0x00,0xd7,0xb9,0xba,0x4d,0xe2,0x3b,0x3d,0x35,0x7a,0x3f,0x88,
+       0x67,0x95,0xe7,0xfd,0x9f,0xe9,0x0a,0x0d,0x79,0x3a,0x9e,0x21,0x8f,0xcb,0xe4,0x67,
+       0x24,0xae,0x0c,0xda,0xb3,0xcc,0xec,0x36,0xb4,0xa8,0x4d,0xf1,0x3d,0xad,0xe4,0x8c,
+       0x63,0x92,0x54,0xb7,0xb2,0x02,0xa2,0x00,0x62,0x8b,0x04,0xac,0xa0,0x17,0xad,0x17,
+       0x9a,0x05,0x0d,0xd7,0xb3,0x08,0x02,0xc5,0x26,0xcf,0xdd,0x05,0x42,0xfc,0x13,0x6d,
+       0x9f,0xb1,0xf3,0x4f,0x82,0x1d,0xef,0x01,0xc9,0x91,0xea,0x37,0x1b,0x79,0x28,0xfa,
+       0xbf,0x9f,0xb3,0xeb,0x82,0x4f,0x10,0xc6,0x4b,0xa4,0x08,0xf7,0x8e,0xf2,0x00,0xea,
+       0x04,0x97,0x80,0x9f,0x65,0x86,0xde,0x6b,0xc7,0xda,0x83,0xfc,0xad,0x4a,0xaf,0x52,
+       0x8b,0x4d,0x33,0xee,0x49,0x87,0x2f,0x3b,0x60,0x45,0x66,0x8f,0xe6,0x89,0xcc,0xb1,
+       0x92,0x02,0x17,0x2b,0x7b,0x8e,0x90,0x47,0x84,0x84,0x59,0x95,0x81,0xd8,0xe0,0xf3,
+       0x87,0xe0,0x04,0x09,0xfd,0xcc,0x3a,0x21,0x34,0xfa,0xec,0xbe,0xf5,0x9c,0xcf,0x55,
+       0x80,0x7b,0xe3,0x75,0x9d,0x36,0x68,0xab,0x83,0xe3,0xad,0x01,0x53,0x0d,0x8a,0x9a,
+       0xa6,0xb0,0x15,0xc9,0xc5,0xf8,0x9b,0x51,0x32,0xcf,0x97,0x6c,0xfe,0x4a,0x56,0x3c,
+       0xc8,0x8f,0x4a,0x70,0x23,0x4f,0xf6,0xf7,0xe6,0x9f,0x09,0xcd,0x8f,0xea,0x20,0x7d,
+       0x34,0xc0,0xc5,0xc0,0x34,0x06,0x6f,0x8b,0xeb,0x04,0x54,0x3f,0x0e,0xcd,0xe2,0x85,
+       0xab,0x94,0x3e,0x91,0x6c,0x18,0x6f,0x96,0x5d,0xf2,0x8b,0x10,0xe9,0x90,0x43,0xb0,
+       0x61,0x52,0xac,0xcf,0x75,0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,
+       0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x09,0x63,
+       0x42,0xad,0xe5,0xa3,0xf6,0xc9,0x5d,0x08,0xf2,0x78,0x7b,0xeb,0x8a,0xef,0x50,0x00,
+       0xc8,0xeb,0xe9,0x26,0x94,0xcb,0x84,0x10,0x7e,0x42,0x6b,0x86,0x38,0x57,0xa6,0x02,
+       0x98,0x5a,0x2c,0x8f,0x44,0x32,0x1b,0x97,0x8c,0x7e,0x4b,0xd8,0xe8,0xe8,0x0f,0x4a,
+       0xb9,0x31,0x9f,0xf6,0x9f,0x0e,0x67,0x26,0x05,0x2a,0x99,0x14,0x35,0x41,0x47,0x9a,
+       0xfa,0x12,0x94,0x0b,0xe9,0x27,0x7c,0x71,0x20,0xd7,0x8d,0x3b,0x97,0x19,0x2d,0x15,
+       0xff,0xa4,0xf3,0x89,0x8d,0x29,0x5f,0xf6,0x3f,0x93,0xaf,0x78,0x61,0xe4,0xe1,0x2e,
+       0x75,0xc1,0x2c,0xc4,0x76,0x95,0x19,0xf8,0x37,0xdc,0xd8,0x00,0x7a,0x3c,0x0f,0x49,
+       0x2e,0x88,0x09,0x16,0xb3,0x92,0x33,0xdf,0x77,0x83,0x4f,0xb5,0x9e,0x30,0x8c,0x48,
+       0x1d,0xd8,0x84,0xfb,0xf1,0xb9,0xa0,0xbe,0x25,0xff,0x4c,0xeb,0xef,0x2b,0xcd,0xfa,
+       0x0b,0x94,0x66,0x3b,0x28,0x08,0x3f,0x3a,0xda,0x41,0xd0,0x6b,0xab,0x5e,0xbb,0x8a,
+       0x9f,0xdc,0x98,0x3e,0x59,0x37,0x48,0xbe,0x69,0xde,0x85,0x82,0xf2,0x53,0x8b,0xe4,
+       0x44,0xe4,0x71,0x91,0x14,0x85,0x0e,0x1e,0x79,0xdd,0x62,0xf5,0xdc,0x25,0x89,0xab,
+       0x50,0x5b,0xaa,0xae,0xe3,0x64,0x6a,0x23,0x34,0xd7,0x30,0xe2,0x2a,0xc8,0x81,0x0c,
+       0xec,0xd2,0x31,0xc6,0x1e,0xb6,0xc0,0x57,0xd9,0xe1,0x14,0x06,0x9b,0xf8,0x51,0x69,
+       0x47,0xf0,0x9c,0xcd,0x69,0xef,0x8e,0x5f,0x62,0xda,0x10,0xf7,0x3c,0x6d,0x0f,0x33,
+       0xec,0x6f,0xfd,0x94,0x07,0x16,0x41,0x32,0x06,0xa4,0xe1,0x08,0x31,0x87,
+};
+chunk_t certchunk = chunk_from_buf(certbuf);
+
+/*******************************************************************************
+ * auth info test
+ ******************************************************************************/
+bool test_auth_info()
+{
+       auth_info_t *auth = auth_info_create(), *auth2;
+       certificate_t *c1, *c2;
+       enumerator_t *enumerator;
+       int round = 0;
+       void *value;
+       auth_item_t type;
+       
+       c1 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+                                                       BUILD_BLOB_ASN1_DER, chunk_clone(certchunk),
+                                                       BUILD_END);
+       if (!c1)
+       {
+               return FALSE;
+       }
+       
+       auth->add_item(auth, AUTHN_SUBJECT_CERT, c1);
+       if (!auth->get_item(auth, AUTHN_SUBJECT_CERT, (void**)&c2))
+       {
+               return FALSE;
+       }
+       if (!c1->equals(c1, c2))
+       {
+               return FALSE;
+       }
+       
+       enumerator = auth->create_item_enumerator(auth);
+       while (enumerator->enumerate(enumerator, &type, &value))
+       {
+               round++;
+               if (round == 1 && type == AUTHN_SUBJECT_CERT && value == c1)
+               {
+                       continue;
+               }
+               return FALSE;
+       }
+       enumerator->destroy(enumerator);
+       
+       auth2 = auth_info_create();
+       auth2->add_item(auth2, AUTHN_CA_CERT, c1);
+       auth2->merge(auth2, auth);
+       
+       round = 0;
+       enumerator = auth2->create_item_enumerator(auth2);
+       while (enumerator->enumerate(enumerator, &type, &value))
+       {
+               round++;
+               if (round == 1 && type == AUTHN_CA_CERT && value == c1)
+               {
+                       continue;
+               }
+               if (round == 2 && type == AUTHN_SUBJECT_CERT && value == c1)
+               {
+                       continue;
+               }
+               return FALSE;
+       }
+       enumerator->destroy(enumerator);
+       auth->destroy(auth);
+       auth2->destroy(auth2);
+       c1->destroy(c1);
+       return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_curl.c b/src/charon/plugins/unit_tester/tests/test_curl.c
new file mode 100644 (file)
index 0000000..c011617
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <daemon.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+/*******************************************************************************
+ * curl get test
+ ******************************************************************************/
+
+bool test_curl_get()
+{
+       chunk_t chunk;
+       
+       if (lib->fetcher->fetch(lib->fetcher, "http://www.strongswan.org",
+                                                       &chunk, FETCH_END) != SUCCESS)
+       {
+               return FALSE;
+       }
+       free(chunk.ptr);
+       
+       if (lib->fetcher->fetch(lib->fetcher, "http://www.google.com",
+                                                       &chunk, FETCH_END) != SUCCESS)
+       {
+               return FALSE;
+       }
+       free(chunk.ptr);
+       return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_enumerator.c b/src/charon/plugins/unit_tester/tests/test_enumerator.c
new file mode 100644 (file)
index 0000000..d17d62b
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * 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>
+
+
+/*******************************************************************************
+ * linked list remove test
+ ******************************************************************************/
+bool test_list_remove()
+{
+       void *a = (void*)1, *b = (void*)2;
+       linked_list_t *list;
+       
+       list = linked_list_create();
+       list->insert_last(list, a);
+       if (list->remove(list, a, NULL) != 1)
+       {
+               return FALSE;
+       }
+       list->insert_last(list, a);
+       list->insert_first(list, a);
+       list->insert_last(list, a);
+       list->insert_last(list, b);
+       if (list->remove(list, a, NULL) != 3)
+       {
+               return FALSE;
+       }
+       if (list->remove(list, a, NULL) != 0)
+       {
+               return FALSE;
+       }
+       if (list->get_count(list) != 1)
+       {
+               return FALSE;
+       }
+       if (list->remove(list, b, NULL) != 1)
+       {
+               return FALSE;
+       }
+       if (list->remove(list, b, NULL) != 0)
+       {
+               return FALSE;
+       }
+       list->destroy(list);
+       return TRUE;
+}
+
+/*******************************************************************************
+ * Simple insert first/last and enumerate test
+ ******************************************************************************/
+bool test_enumerate()
+{
+       int round, x;
+       void *a = (void*)4, *b = (void*)3, *c = (void*)2, *d = (void*)5, *e = (void*)1;
+       linked_list_t *list;
+       enumerator_t *enumerator;
+       
+       list = linked_list_create();
+       
+       list->insert_last(list, a);
+       list->insert_first(list, b);
+       list->insert_first(list, c);
+       list->insert_last(list, d);
+       list->insert_first(list, e);
+       
+       round = 1;
+       enumerator = list->create_enumerator(list);
+       while (enumerator->enumerate(enumerator, &x))
+       {
+               if (round != x)
+               {
+                       return FALSE;
+               }
+               round++;
+       }
+       enumerator->destroy(enumerator);
+       
+       list->destroy(list);
+       return TRUE;
+}
+
+/*******************************************************************************
+ * nested enumerator test
+ ******************************************************************************/
+
+static bool bad_data;
+
+static enumerator_t* create_inner(linked_list_t *outer, void *data)
+{
+       if (data != (void*)101)
+       {
+               bad_data = TRUE;
+       }
+       return outer->create_enumerator(outer);
+}
+
+
+static void destroy_data(void *data)
+{
+       if (data != (void*)101)
+       {
+               bad_data = TRUE;
+       }
+}
+
+bool test_enumerate_nested()
+{
+       int round, x;
+       void *a = (void*)1, *b = (void*)2, *c = (void*)3, *d = (void*)4, *e = (void*)5;
+       linked_list_t *list, *l1, *l2, *l3;
+       enumerator_t *enumerator;
+       
+       bad_data = FALSE;
+       list = linked_list_create();
+       l1 = linked_list_create();
+       l2 = linked_list_create();
+       l3 = linked_list_create();
+       list->insert_last(list, l1);
+       list->insert_last(list, l2);
+       list->insert_last(list, l3);
+       
+       l1->insert_last(l1, a);
+       l1->insert_last(l1, b);
+       l3->insert_last(l3, c);
+       l3->insert_last(l3, d);
+       l3->insert_last(l3, e);
+       
+       round = 1;
+       enumerator = enumerator_create_nested(list->create_enumerator(list),
+                                       (void*)create_inner, (void*)101, destroy_data);
+       while (enumerator->enumerate(enumerator, &x))
+       {
+               if (round != x)
+               {
+                       return FALSE;
+               }
+               round++;
+       }
+       enumerator->destroy(enumerator);
+       
+       list->destroy(list);
+       l1->destroy(l1);
+       l2->destroy(l2);
+       l3->destroy(l3);
+       return !bad_data;
+}
+
+
+/*******************************************************************************
+ * filtered enumerator test
+ ******************************************************************************/
+static bool filter(void *data, int *v, int *vo, int *w, int *wo,
+                                  int *x, int *xo, int *y, int *yo, int *z, int *zo)
+{
+       int val = *v;
+
+       *vo = val++;
+       *wo = val++;
+       *xo = val++;
+       *yo = val++;
+       *zo = val++;
+       if (data != (void*)101)
+       {
+               return FALSE;
+       }
+       return TRUE;
+}
+
+bool test_enumerate_filtered()
+{
+       int round, v, w, x, y, z;
+       void *a = (void*)1, *b = (void*)2, *c = (void*)3, *d = (void*)4, *e = (void*)5;
+       linked_list_t *list;
+       enumerator_t *enumerator;
+       
+       bad_data = FALSE;
+       list = linked_list_create();
+       
+       list->insert_last(list, a);
+       list->insert_last(list, b);
+       list->insert_last(list, c);
+       list->insert_last(list, d);
+       list->insert_last(list, e);
+       
+       round = 1;
+       enumerator = enumerator_create_filter(list->create_enumerator(list),
+                                                                       (void*)filter, (void*)101, destroy_data);
+       while (enumerator->enumerate(enumerator, &v, &w, &x, &y, &z))
+       {
+               if (v != round || w != round + 1 || x != round + 2 ||
+                       y != round + 3 || z != round + 4)
+               {
+                       return FALSE;
+               }
+               round++;
+       }
+       enumerator->destroy(enumerator);
+       
+       list->destroy(list);
+       return !bad_data;
+}
diff --git a/src/charon/plugins/unit_tester/tests/test_fips_prf.c b/src/charon/plugins/unit_tester/tests/test_fips_prf.c
new file mode 100644 (file)
index 0000000..56ba556
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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)
+       {
+               return FALSE;
+       }
+       prf->set_key(prf, key);
+       prf->allocate_bytes(prf, seed, &result);
+       prf->destroy(prf);
+       if (!chunk_equals(result, expected))
+       {
+               chunk_free(&result);
+               return FALSE;
+       }
+       chunk_free(&result);
+       return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_mutex.c b/src/charon/plugins/unit_tester/tests/test_mutex.c
new file mode 100644 (file)
index 0000000..a305d50
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <library.h>
+#include <utils/mutex.h>
+
+#include <unistd.h>
+#include <sched.h>
+#include <pthread.h>
+
+
+static mutex_t *mutex;
+
+static int locked = 0;
+
+static bool failed = FALSE;
+
+static pthread_barrier_t barrier;
+
+static void* run(void* null)
+{
+       int i;
+
+       /* wait for all threads before getting in action */
+       pthread_barrier_wait(&barrier);
+
+       for (i = 0; i < 100; i++)
+       {
+               mutex->lock(mutex);
+               mutex->lock(mutex);
+               mutex->lock(mutex);
+               locked++;
+               sched_yield();
+               if (locked > 1)
+               {
+                       failed = TRUE;
+               }       
+               locked--;
+               mutex->unlock(mutex);
+               mutex->unlock(mutex);
+               mutex->unlock(mutex);
+       }
+       return NULL;
+}
+
+#define THREADS 20
+
+/*******************************************************************************
+ * mutex test
+ ******************************************************************************/
+bool test_mutex()
+{
+       int i;
+       pthread_t threads[THREADS];
+       
+       mutex = mutex_create(MUTEX_RECURSIVE);
+       
+       for (i = 0; i < 10; i++)
+       {
+               mutex->lock(mutex);
+               mutex->unlock(mutex);
+       }
+       for (i = 0; i < 10; i++)
+       {
+               mutex->lock(mutex);
+       }
+       for (i = 0; i < 10; i++)
+       {
+               mutex->unlock(mutex);
+       }
+       
+       pthread_barrier_init(&barrier, NULL, THREADS);
+       
+       for (i = 0; i < THREADS; i++)
+       {
+               pthread_create(&threads[i], NULL, run, NULL);
+       }
+       for (i = 0; i < THREADS; i++)
+       {
+               pthread_join(threads[i], NULL);
+       }
+       pthread_barrier_destroy(&barrier);
+       
+       mutex->destroy(mutex);
+       
+       return !failed;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_mysql.c b/src/charon/plugins/unit_tester/tests/test_mysql.c
new file mode 100644 (file)
index 0000000..ff3d38a
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <library.h>
+#include <daemon.h>
+#include <utils/enumerator.h>
+
+/*******************************************************************************
+ * mysql simple test
+ ******************************************************************************/
+bool test_mysql()
+{
+       database_t *db;
+       char *txt = "I'm a superduper test";
+       char buf[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
+       chunk_t data = chunk_from_buf(buf);
+       int row;
+       chunk_t qdata;
+       char *qtxt;
+       bool good = FALSE;
+       enumerator_t *enumerator;
+       
+       db = lib->db->create(lib->db, "mysql://testuser:testpass@localhost/test");
+       if (!db)
+       {
+               return FALSE;
+       }
+       if (db->execute(db, NULL, "CREATE TABLE test ("
+                                                               "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, "
+                                                               "txt TEXT, data BLOB)") < 0)
+       {
+               return FALSE;
+       }
+       if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)",
+                                       DB_TEXT, txt, DB_BLOB, data) < 0)
+       {
+               return FALSE;
+       }
+       if (row != 1)
+       {
+               return FALSE;
+       }
+       enumerator = db->query(db, "SELECT txt, data FROM test WHERE id = ?",
+                                                  DB_INT, row,
+                                                  DB_TEXT, DB_BLOB);
+       if (!enumerator)
+       {
+               return FALSE;
+       }
+       while (enumerator->enumerate(enumerator, &qtxt, &qdata))
+       {
+               if (good)
+               {       /* only one row */
+                       good = FALSE;
+                       break;
+               }
+               if (streq(qtxt, txt) && chunk_equals(data, qdata))
+               {
+                       good = TRUE;
+               }
+       }
+       enumerator->destroy(enumerator);
+       if (!good)
+       {
+               return FALSE;
+       }
+       if (db->execute(db, NULL, "DELETE FROM test WHERE id = ?", DB_INT, row) != 1)
+       {
+               return FALSE;
+       }
+       if (db->execute(db, NULL, "DROP TABLE test") < 0)
+       {
+               return FALSE;
+       }
+       db->destroy(db);
+       return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/tests/test_sqlite.c b/src/charon/plugins/unit_tester/tests/test_sqlite.c
new file mode 100644 (file)
index 0000000..d152fc5
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <library.h>
+#include <daemon.h>
+#include <utils/enumerator.h>
+
+#include <unistd.h>
+
+
+#define DBFILE "/tmp/strongswan-test.db"
+
+/*******************************************************************************
+ * sqlite simple test
+ ******************************************************************************/
+bool test_sqlite()
+{
+       database_t *db;
+       char *txt = "I'm a superduper test";
+       char buf[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
+       chunk_t data = chunk_from_buf(buf);
+       int row;
+       chunk_t qdata;
+       char *qtxt;
+       bool good = FALSE;
+       enumerator_t *enumerator;
+       
+       db = lib->db->create(lib->db, "sqlite://" DBFILE);
+       if (!db)
+       {
+               return FALSE;
+       }
+       if (db->execute(db, NULL, "CREATE TABLE test (txt TEXT, data BLOB)") < 0)
+       {
+               return FALSE;
+       }
+       if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)",
+                                       DB_TEXT, txt, DB_BLOB, data) < 0)
+       {
+               return FALSE;
+       }
+       if (row != 1)
+       {
+               return FALSE;
+       }
+       enumerator = db->query(db, "SELECT txt, data FROM test WHERE oid = ?",
+                                                  DB_INT, row,
+                                                  DB_TEXT, DB_BLOB);
+       if (!enumerator)
+       {
+               return FALSE;
+       }
+       while (enumerator->enumerate(enumerator, &qtxt, &qdata))
+       {
+               if (good)
+               {       /* only one row */
+                       good = FALSE;
+                       break;
+               }
+               if (streq(qtxt, txt) && chunk_equals(data, qdata))
+               {
+                       good = TRUE;
+               }
+       }
+       enumerator->destroy(enumerator);
+       if (!good)
+       {
+               return FALSE;
+       }
+       if (db->execute(db, NULL, "DELETE FROM test WHERE oid = ?", DB_INT, row) != 1)
+       {
+               return FALSE;
+       }
+       if (db->execute(db, NULL, "DROP TABLE test") < 0)
+       {
+               return FALSE;
+       }
+       db->destroy(db);
+       unlink(DBFILE);
+       return TRUE;
+}
+
diff --git a/src/charon/plugins/unit_tester/unit_tester.c b/src/charon/plugins/unit_tester/unit_tester.c
new file mode 100644 (file)
index 0000000..f996a49
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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$
+ */
+
+#include "unit_tester.h"
+
+#include <daemon.h>
+
+typedef struct private_unit_tester_t private_unit_tester_t;
+typedef struct unit_test_t unit_test_t;
+typedef enum test_status_t test_status_t;
+
+/**
+ * private data of unit_tester
+ */
+struct private_unit_tester_t {
+
+       /**
+        * public functions
+        */
+       unit_tester_t public;
+};
+
+struct unit_test_t {
+       
+       /**
+        * name of the test
+        */
+       char *name;
+       
+       /**
+        * test function
+        */
+       bool (*test)(void);
+       
+       /**
+        * run the test?
+        */
+       bool enabled;
+};
+
+#undef DEFINE_TEST
+#define DEFINE_TEST(name, function, enabled) bool function();
+#include <plugins/unit_tester/tests.h>
+#undef DEFINE_TEST
+#define DEFINE_TEST(name, function, enabled) {name, function, enabled},
+static unit_test_t tests[] = {
+#include <plugins/unit_tester/tests.h>
+};
+
+static void run_tests(private_unit_tester_t *this)
+{
+       int i, run = 0, failed = 0, success = 0, skipped = 0;
+       
+       DBG1(DBG_CFG, "running unit tests, %d tests registered",
+                sizeof(tests)/sizeof(unit_test_t));
+       
+       for (i = 0; i < sizeof(tests)/sizeof(unit_test_t); i++)
+       {
+               if (tests[i].enabled)
+               {
+                       run++;
+                       if (tests[i].test())
+                       {
+                               DBG1(DBG_CFG, "test '%s' successful", tests[i].name);
+                               success++;
+                       }
+                       else
+                       {
+                               DBG1(DBG_CFG, "test '%s' failed", tests[i].name);
+                               failed++;
+                       }
+               }
+               else
+               {
+                       DBG1(DBG_CFG, "test '%s' disabled", tests[i].name);
+                       skipped++;
+               }
+       }
+       DBG1(DBG_CFG, "%d/%d tests successful (%d failed, %d disabled)",
+                success, run, failed, skipped);
+}
+
+/**
+ * Implementation of 2007_t.destroy
+ */
+static void destroy(private_unit_tester_t *this)
+{
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_unit_tester_t *this = malloc_thing(private_unit_tester_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       run_tests(this);
+       
+       return &this->public.plugin;
+}
+
similarity index 51%
rename from src/charon/control/interfaces/xml_interface.h
rename to src/charon/plugins/unit_tester/unit_tester.h
index 6d88c384262d22f3d9d83bf1270952b8aa1cb541..a87c86251f7879f0bfeabcba35bba04da4e48596 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file xml_interface.h
- *
- * @brief Interface of xml_interface_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 unit_tester unit_tester
+ * @{ @ingroup cplugins
  */
 
-#ifndef XML_INTERFACE_H_
-#define XML_INTERFACE_H_
+#ifndef UNIT_TESTER_H_
+#define UNIT_TESTER_H_
 
-typedef struct xml_interface_t xml_interface_t;
+#include <plugins/plugin.h>
 
-#include <control/interfaces/interface.h>
+typedef struct unit_tester_t unit_tester_t;
 
 /**
- * @brief The XML interface uses a socket to communicate using XML.
- * 
- * @b Constructors:
- * - xml_interface_create()
- * 
- * @ingroup interfaces
+ * Unit testing plugin.
+ *
+ * The unit testing plugin runs tests on plugin initialization. Tests are 
+ * defined in tests.h using the DEFINE_TEST macro. Implementation of the
+ * tests is done in the tests folder. Each test has uses a function which
+ * returns TRUE for success or FALSE for failure.
  */
-struct xml_interface_t {
-       
+struct unit_tester_t {
+
        /**
-        * implements interface_t.
+        * Implements the plugin interface.
         */
-       interface_t interface;
+       plugin_t plugin;
 };
 
-
 /**
- * @brief Create the XML interface.
- *
- * @return                     stroke_t object
- * 
- * @ingroup interfaces
+ * Create a unit_tester plugin.
  */
-interface_t *interface_create(void);
-
-#endif /* XML_INTERFACE_H_ */
+plugin_t *plugin_create();
 
+#endif /* UNIT_TESTER_H_ @}*/
diff --git a/src/charon/plugins/xml/Makefile.am b/src/charon/plugins/xml/Makefile.am
new file mode 100644 (file)
index 0000000..0e4735a
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon ${xml_CFLAGS}
+
+AM_CFLAGS = -rdynamic -DIPSEC_PIDDIR=\"${piddir}\"
+
+plugin_LTLIBRARIES = libcharon-xml.la
+libcharon_xml_la_SOURCES = xml.h xml.c
+libcharon_xml_la_LDFLAGS = -module
+libcharon_xml_la_LIBADD = ${xml_LIBS}
+
similarity index 92%
rename from src/charon/control/interfaces/xml_interface.c
rename to src/charon/plugins/xml/xml.c
index aa2a554a0b00df5bf5095308dfba6621d41c5e7a..85778f608948e464bf9a913c4d3252083fca8fd1 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file xml_interface.c
- * 
- * @brief Implementation of xml_interface_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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>
 
-#include "xml_interface.h"
+#include "xml.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <processing/jobs/callback_job.h>
 
 
-typedef struct private_xml_interface_t private_xml_interface_t;
+typedef struct private_xml_t private_xml_t;
 
 /**
- * Private data of an xml_interface_t object.
+ * Private data of an xml_t object.
  */
-struct private_xml_interface_t {
+struct private_xml_t {
 
        /**
         * Public part of xml_t object.
         */
-       xml_interface_t public;
+       xml_t public;
        
        /**
         * XML unix socket fd
@@ -299,16 +294,16 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
  */
 static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        peer_cfg_t *peer_cfg;
 
        /* <configlist> */
        xmlTextWriterStartElement(writer, "configlist");
        
-       iterator = charon->backends->create_iterator(charon->backends);
-       while (iterator->iterate(iterator, (void**)&peer_cfg))
+       enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
+       while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
        {
-               iterator_t *children;
+               enumerator_t *children;
                child_cfg_t *child_cfg;
                ike_cfg_t *ike_cfg;
                linked_list_t *list;
@@ -334,8 +329,8 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
                
                /* <childconfiglist> */
                xmlTextWriterStartElement(writer, "childconfiglist");
-               children = peer_cfg->create_child_cfg_iterator(peer_cfg);
-               while (children->iterate(children, (void**)&child_cfg))
+               children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
+               while (children->enumerate(children, &child_cfg))
                {
                        /* <childconfig> */
                        xmlTextWriterStartElement(writer, "childconfig");               
@@ -356,7 +351,7 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
                /* </peerconfig> */
                xmlTextWriterEndElement(writer);        
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        /* </configlist> */
        xmlTextWriterEndElement(writer);
 }
@@ -406,15 +401,15 @@ static void request_control_terminate(xmlTextReaderPtr reader,
                xmlTextWriterStartElement(writer, "log");
                if (ike)
                {
-                       status = charon->interfaces->terminate_ike(
-                                       charon->interfaces,     id, 
-                                       (interface_manager_cb_t)xml_callback, writer);
+                       status = charon->controller->terminate_ike(
+                                       charon->controller,     id, 
+                                       (controller_cb_t)xml_callback, writer);
                }
                else
                {
-                       status = charon->interfaces->terminate_child(
-                                       charon->interfaces,     id, 
-                                       (interface_manager_cb_t)xml_callback, writer);
+                       status = charon->controller->terminate_child(
+                                       charon->controller,     id, 
+                                       (controller_cb_t)xml_callback, writer);
                }
                /* </log> */
                xmlTextWriterEndElement(writer);
@@ -435,7 +430,7 @@ static void request_control_initiate(xmlTextReaderPtr reader,
                status_t status = FAILED;
                peer_cfg_t *peer;
                child_cfg_t *child = NULL;
-               iterator_t *iterator;
+               enumerator_t *enumerator;
                        
                str = xmlTextReaderConstValue(reader);
                if (str == NULL)
@@ -450,10 +445,10 @@ static void request_control_initiate(xmlTextReaderPtr reader,
                peer = charon->backends->get_peer_cfg_by_name(charon->backends, (char*)str);
                if (peer)
                {
-                       iterator = peer->create_child_cfg_iterator(peer);
+                       enumerator = peer->create_child_cfg_enumerator(peer);
                        if (ike)
                        {
-                               if (!iterator->iterate(iterator, (void**)&child))
+                               if (!enumerator->enumerate(enumerator, &child))
                                {
                                        child = NULL;
                                }
@@ -461,7 +456,7 @@ static void request_control_initiate(xmlTextReaderPtr reader,
                        }
                        else
                        {
-                               while (iterator->iterate(iterator, (void**)&child))
+                               while (enumerator->enumerate(enumerator, &child))
                                {
                                        if (streq(child->get_name(child), str))
                                        {
@@ -471,11 +466,11 @@ static void request_control_initiate(xmlTextReaderPtr reader,
                                        child = NULL;
                                }
                        }
-                       iterator->destroy(iterator);
+                       enumerator->destroy(enumerator);
                        if (child)
                        {
-                               status = charon->interfaces->initiate(charon->interfaces,
-                                                       peer, child, (interface_manager_cb_t)xml_callback,
+                               status = charon->controller->initiate(charon->controller,
+                                                       peer, child, (controller_cb_t)xml_callback,
                                                        writer);
                        }
                        else
@@ -667,7 +662,7 @@ static job_requeue_t process(int *fdp)
 /**
  * accept from XML socket and create jobs to process connections
  */
-static job_requeue_t dispatch(private_xml_interface_t *this)
+static job_requeue_t dispatch(private_xml_t *this)
 {
        struct sockaddr_un strokeaddr;
        int oldstate, fd, *fdp, strokeaddrlen = sizeof(strokeaddr);
@@ -696,7 +691,7 @@ static job_requeue_t dispatch(private_xml_interface_t *this)
 /**
  * Implementation of itnerface_t.destroy.
  */
-static void destroy(private_xml_interface_t *this)
+static void destroy(private_xml_t *this)
 {
        this->job->cancel(this->job);
        close(this->socket);
@@ -706,13 +701,13 @@ static void destroy(private_xml_interface_t *this)
 /*
  * Described in header file
  */
-interface_t *interface_create()
+plugin_t *plugin_create()
 {
        struct sockaddr_un unix_addr = { AF_UNIX, IPSEC_PIDDIR "/charon.xml"};
-       private_xml_interface_t *this = malloc_thing(private_xml_interface_t);
+       private_xml_t *this = malloc_thing(private_xml_t);
        mode_t old;
 
-       this->public.interface.destroy = (void (*)(interface_t*))destroy;
+       this->public.plugin.destroy = (void (*)(plugin_t*))destroy;
        
        /* set up unix socket */
        this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -749,6 +744,6 @@ interface_t *interface_create()
        this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL);
        charon->processor->queue_job(charon->processor, (job_t*)this->job);
        
-       return &this->public.interface;
+       return &this->public.plugin;
 }
 
similarity index 50%
rename from src/charon/control/interfaces/dbus_interface.h
rename to src/charon/plugins/xml/xml.h
index 0ce57bbbce069d5d5d38de2b7f9b4f1982cdf9f1..289fca5f6f76b31354e98277760d689ad026c317 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file dbus_interface.h
- *
- * @brief Interface of dbus_interface_t.
- *
- */
-
 /*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 DBUS_INTERFACE_H_
-#define DBUS_INTERFACE_H_
+/**
+ * @defgroup xml xml
+ * @ingroup cplugins
+ *
+ * @defgroup xml_i xml
+ * @{ @ingroup xml
+ */
+
+#ifndef XML_H_
+#define XML_H_
 
-typedef struct dbus_interface_t dbus_interface_t;
+#include <plugins/plugin.h>
 
-#include <control/interfaces/interface.h>
+typedef struct xml_t xml_t;
 
 /**
- * @brief The DBUS interface uses the DBUS system bus to communicate.
- * 
- * @b Constructors:
- * - dbus_interface_create()
- * 
- * @ingroup interfaces
+ * XML configuration and control interface.
+ *
+ * The XML interface uses a socket and a to communicate. The syntax is strict
+ * XML, defined in the schema.xml specification.
  */
-struct dbus_interface_t {
-       
+struct xml_t {
+
        /**
-        * implements interface_t.
+        * implements the plugin interface.
         */
-       interface_t interface;
+       plugin_t plugin;
 };
 
-
 /**
- * @brief Create the DBUS interface.
- *
- * @return                     stroke_t object
- * 
- * @ingroup interfaces
+ * Create a xml plugin instance.
  */
-interface_t *interface_create();
-
-#endif /* DBUS_INTERFACE_H_ */
+plugin_t *plugin_create();
 
+#endif /* XML_H_ @}*/
index 48a77f5581893390838add57fd9e4c086251323c..e066cbac5d3ad68792c81a58f4d229aa77106608 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file acquire_job.c
- * 
- * @brief Implementation of acquire_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "acquire_job.h"
index 2269662152ea479ef1c8ad0285b99a27de197463..b256c7fc15e572eb460b6078fede17312924246b 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file acquire_job.h
- * 
- * @brief Interface of acquire_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 acquire_job acquire_job
+ * @{ @ingroup jobs
  */
 
 #ifndef ACQUIRE_JOB_H_
@@ -29,14 +29,9 @@ typedef struct acquire_job_t acquire_job_t;
 #include <processing/jobs/job.h>
 
 /**
- * @brief Class representing an ACQUIRE Job.
+ * Class representing an ACQUIRE Job.
  * 
  * This job initiates a CHILD SA on kernel request.
- * 
- * @b Constructors:
- *  - acquire_job_create()
- * 
- * @ingroup jobs
  */
 struct acquire_job_t {
        /**
@@ -46,15 +41,13 @@ struct acquire_job_t {
 };
 
 /**
- * @brief Creates a job of type ACQUIRE.
+ * 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
  * @return                     acquire_job_t object
- * 
- * @ingroup jobs
  */
 acquire_job_t *acquire_job_create(u_int32_t reqid);
 
-#endif /* REKEY_CHILD_SA_JOB_H_ */
+#endif /* REKEY_CHILD_SA_JOB_H_ @} */
index 53297916eb0aa524289ae350128f094aada92c22..ae2236a3eeef1c99fac2ffb38c0d29e8311868f5 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file callback_job.c
- * 
- * @brief Implementation of callback_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "callback_job.h"
index 169f2d2070805ef6f15a8822f2e317ce56086a98..1fa9fa2d65a226ea49df3f89e70c23ac3afb89b2 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file callback_job.h
- * 
- * @brief Interface of callback_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 callback_job callback_job
+ * @{ @ingroup jobs
  */
 
 #ifndef CALLBACK_JOB_H_
@@ -32,12 +32,10 @@ typedef struct callback_job_t callback_job_t;
 typedef enum job_requeue_t job_requeue_t;
 
 /**
- * @brief Job requeueing policy
+ * Job requeueing policy
  *
  * The job requeueing policy defines how a job is handled when the callback
  * function returns.
- *
- * @ingroup jobs
  */
 enum job_requeue_t {
 
@@ -58,20 +56,18 @@ enum job_requeue_t {
 };
 
 /**
- * @brief The callback function to use for the callback job.
+ * The callback function to use for the callback job.
  *
  * This is the function to use as callback for a callback job. It receives
  * a parameter supplied to the callback jobs constructor.
  *
  * @param data                 param supplied to job
  * @return                             requeing policy how to requeue the job
- *
- * @ingroup jobs
  */
 typedef job_requeue_t (*callback_job_cb_t)(void *data);
 
 /**
- * @brief Cleanup function to use for data cleanup.
+ * Cleanup function to use for data cleanup.
  *
  * The callback has an optional user argument which receives data. However,
  * this data may be cleaned up if it is allocated. This is the function
@@ -79,22 +75,15 @@ typedef job_requeue_t (*callback_job_cb_t)(void *data);
  *
  * @param data                 param supplied to job
  * @return                             requeing policy how to requeue the job
- *
- * @ingroup jobs
  */
 typedef void (*callback_job_cleanup_t)(void *data);
 
 /**
- * @brief Class representing an callback Job.
+ * Class representing an callback Job.
  *
  * This is a special job which allows a simple callback function to
  * be executed by a thread of the thread pool. This allows simple execution
  * of asynchronous methods, without to manage threads.
- *
- * @b Constructors:
- * - callback_job_create()
- *
- * @ingroup jobs
  */
 struct callback_job_t {
        /**
@@ -103,15 +92,13 @@ struct callback_job_t {
        job_t job_interface;
        
        /**
-        * @brief Cancel the jobs thread and wait for its termination.
-        *
-        * @param this          calling object
+        * Cancel the jobs thread and wait for its termination.
         */
        void (*cancel)(callback_job_t *this);
 };
 
 /**
- * @brief Creates a callback job.
+ * Creates a callback job.
  *
  * The cleanup function is called when the job gets destroyed to destroy
  * the associated data.
@@ -124,12 +111,9 @@ struct callback_job_t {
  * @param cleanup                      destructor for data on destruction, or NULL
  * @param parent                       parent of this job
  * @return                                     callback_job_t object
- * 
- * @ingroup jobs
  */
 callback_job_t *callback_job_create(callback_job_cb_t cb, void *data,
                                                                        callback_job_cleanup_t cleanup,
                                                                        callback_job_t *parent);
 
-#endif /* CALLBACK_JOB_H_ */
-
+#endif /* CALLBACK_JOB_H_ @} */
index 23f3302936f8e19aa08b01ae8b240fb25039d13b..e3492c73df5d927f14097235435aa394410432b1 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file delete_child_sa_job.c
- *
- * @brief Implementation of delete_child_sa_job_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "delete_child_sa_job.h"
index 0b90e008df3e470c66fe7374082e6c4403f594c5..35d884be7d4fba0241df4dbe2301e45537a2cc18 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file delete_child_sa_job.h
- * 
- * @brief Interface of delete_child_sa_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 delete_child_sa_job delete_child_sa_job
+ * @{ @ingroup jobs
  */
 
 #ifndef DELETE_CHILD_SA_JOB_H_
@@ -32,14 +32,9 @@ typedef struct delete_child_sa_job_t delete_child_sa_job_t;
 
 
 /**
- * @brief Class representing an DELETE_CHILD_SA Job.
+ * Class representing an DELETE_CHILD_SA Job.
  * 
  * This job initiates the delete of a CHILD SA.
- * 
- * @b Constructors:
- *  - delete_child_sa_job_create()
- * 
- * @ingroup jobs
  */
 struct delete_child_sa_job_t {
        /**
@@ -49,7 +44,7 @@ struct delete_child_sa_job_t {
 };
 
 /**
- * @brief Creates a job of type DELETE_CHILD_SA.
+ * Creates a job of type DELETE_CHILD_SA.
  *
  * The CHILD_SA is identified by its reqid, protocol (AH/ESP) and its
  * inbound SPI.
@@ -58,11 +53,9 @@ struct delete_child_sa_job_t {
  * @param protocol     protocol of the CHILD_SA
  * @param spi          security parameter index of the CHILD_SA
  * @return                     delete_child_sa_job_t object
- * 
- * @ingroup jobs
  */
 delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid, 
                                                                                                  protocol_id_t protocol, 
                                                                                                  u_int32_t spi);
 
-#endif /* DELETE_CHILD_SA_JOB_H_ */
+#endif /* DELETE_CHILD_SA_JOB_H_ @} */
index 8d8c0cf365f03757eb773b83dd15403317979c0f..a4d412fc558ef345120aff9f80857640423b292d 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file delete_ike_sa_job.c
- * 
- * @brief Implementation of delete_ike_sa_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "delete_ike_sa_job.h"
index 11bb46e73667d4a63a931c0558bce82cc2663098..773305d0b2e2a63e93286ae22e4c54c507b87932 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file delete_ike_sa_job.h
- * 
- * @brief Interface of delete_ike_sa_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 delete_child_sa_job delete_child_sa_job
+ * @{ @ingroup jobs
  */
  
 #ifndef DELETE_IKE_SA_JOB_H_
@@ -32,16 +32,11 @@ typedef struct delete_ike_sa_job_t delete_ike_sa_job_t;
 
 
 /**
- * @brief Class representing an DELETE_IKE_SA Job.
+ * Class representing an DELETE_IKE_SA Job.
  *
  * This job is responsible for deleting established or half open IKE_SAs. 
  * A half open IKE_SA is every IKE_SA which hasn't reache the SA_ESTABLISHED
  * state.
- *
- * @b Constructors:
- *  - delete_ike_sa_job_create()
- *
- * @ingroup jobs
  */
 struct delete_ike_sa_job_t {
        
@@ -52,15 +47,13 @@ struct delete_ike_sa_job_t {
 };
 
 /**
- * @brief Creates a job of type DELETE_IKE_SA.
+ * Creates a job of type DELETE_IKE_SA.
  * 
  * @param ike_sa_id                            id of the IKE_SA to delete
  * @param delete_if_established        should the IKE_SA be deleted if it is established?
  * @return                                             created delete_ike_sa_job_t object
- * 
- * @ingroup jobs
  */
 delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id,
                                                                                          bool delete_if_established);
 
-#endif /* DELETE_IKE_SA_JOB_H_ */
+#endif /* DELETE_IKE_SA_JOB_H_ @} */
index b8d516e2276c40a509d2808b813c425f3df2ee61..99da4d1ed5501056040a10c99c6d116456666e0e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file initiate_mediation_job.c
- * 
- * @brief Implementation of initiate_mediation_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 "initiate_mediation_job.h"
 
 #include <sa/ike_sa.h>
index 9fb3b0f7d1422ec7de98160e0ffd6c3a230e8b63..dbc6cca15dea02c6484c2f50e4fe9c1f6e4a2f0d 100644 (file)
@@ -1,9 +1,3 @@
-/**
- * @file initiate_mediation_job.h
- * 
- * @brief Interface of initiate_mediation_job_t.
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 initiate_mediation_job initiate_mediation_job
+ * @{ @ingroup jobs
  */
 
 #ifndef INITIATE_MEDIATION_JOB_H_
@@ -29,15 +30,10 @@ typedef struct initiate_mediation_job_t initiate_mediation_job_t;
 #include <sa/ike_sa_id.h>
 
 /**
- * @brief Class representing a INITIATE_MEDIATION Job.
+ * Class representing a INITIATE_MEDIATION Job.
  * 
  * This job will initiate a mediation on behalf of a mediated connection.
  * If required the mediation connection is established.
- * 
- * @b Constructors:
- * - initiate_mediation_job_create()
- * 
- * @ingroup jobs
  */
 struct initiate_mediation_job_t {
        /**
@@ -47,28 +43,24 @@ struct initiate_mediation_job_t {
 };
 
 /**
- * @brief Creates a job of type INITIATE_MEDIATION.
+ * Creates a job of type INITIATE_MEDIATION.
  * 
  * @param ike_sa_id            identification of the ike_sa as ike_sa_id_t object (gets cloned)
  * @param child_cfg            child config of the child_sa (gets cloned)
  * @return                             job object
- * 
- * @ingroup jobs
  */
 initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id,
                child_cfg_t *child_cfg);
 
 /**
- * @brief Creates a special job of type INITIATE_MEDIATION that reinitiates a
+ * Creates a special job of type INITIATE_MEDIATION that reinitiates a
  * specific connection.
  * 
  * @param mediation_sa_id              identification of the mediation sa (gets cloned)
  * @param mediated_sa_id               identification of the mediated sa (gets cloned)
  * @return                                             job object
- * 
- * @ingroup jobs
  */
 initiate_mediation_job_t *reinitiate_mediation_job_create(ike_sa_id_t *mediation_sa_id,
                ike_sa_id_t *mediated_sa_id);
 
-#endif /*INITIATE_MEDIATION_JOB_H_*/
+#endif /*INITIATE_MEDIATION_JOB_H_ @} */
index 1826c53b414d18bfb4609d8de2ae19f26ef563af..dc7821616013d0f986ac896aeede8527ad7af974 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file job.h
- * 
- * @brief Interface job_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 job job
+ * @{ @ingroup jobs
  */
 
 #ifndef JOB_H_
@@ -28,38 +28,27 @@ typedef struct job_t job_t;
 
 #include <library.h>
 
-
 /**
- * @brief Job-Interface as it is stored in the job queue.
- * 
- * @b Constructors:
- * - None, use specific implementation of the interface.
- * 
- * @ingroup jobs
+ * Job-Interface as it is stored in the job queue.
  */
 struct job_t {
 
        /**
-        * @brief Execute a job.
+        * Execute a job.
         * 
         * The processing facility executes a job using this method. Jobs are
         * one-shot, they destroy themself after execution, so don't use a job
         * once it has been executed.
-        *
-        * @param this                          calling object
         */
        void (*execute) (job_t *this);
 
        /**
-        * @brief Destroy a job.
+        * Destroy a job.
         *
         * Is only called whenever a job was not executed (e.g. due daemon shutdown).
         * After execution, jobs destroy themself.
-        * 
-        * @param job_t calling object
         */
        void (*destroy) (job_t *job);
 };
 
-#endif /* JOB_H_ */
-
+#endif /* JOB_H_ @} */
index 3b9d363d74749a5ac28126edc65cc0598f792ff0..6f3e004c6d7aba3ca5c512e71e52d16ff942132f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file mediation_job.c
- * 
- * @brief Implementation of mediation_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 "mediation_job.h"
 
 #include <encoding/payloads/endpoint_notify.h>
index 6130b2e2758755fcf6d6b2154b7ebe88dccd8385..8bf8a7e636ee35c8cd349e3881d8e45f3468e3d4 100644 (file)
@@ -1,9 +1,3 @@
-/**
- * @file mediation_job.h
- * 
- * @brief Interface of mediation_job_t.
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 mediation_job mediation_job
+ * @{ @ingroup jobs
  */
 
 #ifndef MEDIATION_JOB_H_
@@ -30,14 +31,9 @@ typedef struct mediation_job_t mediation_job_t;
 #include <utils/linked_list.h>
 
 /**
- * @brief Class representing a MEDIATION Job.
+ * Class representing a MEDIATION Job.
  * 
  * This job handles the mediation on the mediation server.
- * 
- * @b Constructors:
- * - mediation_job_create()
- * 
- * @ingroup jobs
  */
 struct mediation_job_t {
        /**
@@ -47,7 +43,7 @@ struct mediation_job_t {
 };
 
 /**
- * @brief Creates a job of type MEDIATION.
+ * Creates a job of type MEDIATION.
  * 
  * Parameters get cloned.
  * 
@@ -58,8 +54,6 @@ struct mediation_job_t {
  * @param endpoints            list of submitted endpoints
  * @param response             TRUE if this is a response
  * @return                             job object
- * 
- * @ingroup jobs
  */
 mediation_job_t *mediation_job_create(identification_t *peer_id,
                identification_t *requester, chunk_t session_id, chunk_t session_key,
@@ -67,7 +61,7 @@ mediation_job_t *mediation_job_create(identification_t *peer_id,
 
 
 /**
- * @brief Creates a special job of type MEDIATION that is used to send a callback
+ * Creates a special job of type MEDIATION that is used to send a callback
  * notification to a peer.
  * 
  * Parameters get cloned.
@@ -75,10 +69,8 @@ mediation_job_t *mediation_job_create(identification_t *peer_id,
  * @param requester            ID of the waiting peer
  * @param peer_id              ID of the requested peer
  * @return                             job object
- * 
- * @ingroup jobs
  */
 mediation_job_t *mediation_callback_job_create(identification_t *requester,
                identification_t *peer_id);
 
-#endif /*MEDIATION_JOB_H_*/
+#endif /*MEDIATION_JOB_H_ @} */
index 91e7a80bf1a5d8f85f7f26d26f8898dcfa5b56ba..9d7ab04f33594acad28e0f1e9c819d160be87964 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file process_message_job.h
- * 
- * @brief Implementation of process_message_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 "process_message_job.h"
 
 #include <daemon.h>
index 5bb18155aa79073331a0a8e8879d34c5e6f60c3c..31c2d11fdf5f4defd268aa44296e227ea2613874 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file process_message_job.h
- * 
- * @brief Interface of process_message_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 process_message_job process_message_job
+ * @{ @ingroup jobs
  */
 
 #ifndef PROCESS_MESSAGE_JOB_H_
@@ -31,12 +31,7 @@ typedef struct process_message_job_t process_message_job_t;
 #include <processing/jobs/job.h>
 
 /**
- * @brief Class representing an PROCESS_MESSAGE job.
- *
- * @b Constructors:
- * - process_message_job_create()
- *
- * @ingroup jobs
+ * Class representing an PROCESS_MESSAGE job.
  */
 struct process_message_job_t {
        /**
@@ -46,13 +41,11 @@ struct process_message_job_t {
 };
 
 /**
- * @brief Creates a job of type PROCESS_MESSAGE.
+ * Creates a job of type PROCESS_MESSAGE.
  * 
  * @param message              message to process
  * @return                             created process_message_job_t object
- * 
- * @ingroup jobs
  */
 process_message_job_t *process_message_job_create(message_t *message);
 
-#endif /*PROCESS_MESSAGE_JOB_H_*/
+#endif /*PROCESS_MESSAGE_JOB_H_ @} */
index f754e5a1ff4b0098e8f50017a949562583bbd4d5..05da225764dfd6ebdb49514dbe3fffafdb1bb1ed 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file rekey_child_sa_job.c
- * 
- * @brief Implementation of rekey_child_sa_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "rekey_child_sa_job.h"
index df86070bcb36df59a0f663d1a1ea54052eda8a11..db1357abe29897fc0b700fa7ab8e0cde68d38382 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file rekey_child_sa_job.h
- * 
- * @brief Interface of rekey_child_sa_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 rekey_child_sa_job rekey_child_sa_job
+ * @{ @ingroup jobs
  */
 
 #ifndef REKEY_CHILD_SA_JOB_H_
@@ -31,14 +31,9 @@ typedef struct rekey_child_sa_job_t rekey_child_sa_job_t;
 #include <config/proposal.h>
 
 /**
- * @brief Class representing an REKEY_CHILD_SA Job.
+ * Class representing an REKEY_CHILD_SA Job.
  *
  * This job initiates the rekeying of a CHILD SA.
- *
- * @b Constructors:
- *  - rekey_child_sa_job_create()
- *
- * @ingroup jobs
  */
 struct rekey_child_sa_job_t {
        /**
@@ -48,7 +43,7 @@ struct rekey_child_sa_job_t {
 };
 
 /**
- * @brief Creates a job of type REKEY_CHILD_SA.
+ * Creates a job of type REKEY_CHILD_SA.
  *
  * The CHILD_SA is identified by its protocol (AH/ESP) and its
  * inbound SPI.
@@ -57,9 +52,8 @@ struct rekey_child_sa_job_t {
  * @param protocol     protocol of the CHILD_SA
  * @param spi          security parameter index of the CHILD_SA
  * @return                     rekey_child_sa_job_t object
- * 
- * @ingroup jobs
  */
-rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid, protocol_id_t protocol, u_int32_t spi);
-
-#endif /* REKEY_CHILD_SA_JOB_H_ */
+rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid, 
+                                                                                               protocol_id_t protocol,
+                                                                                               u_int32_t spi);
+#endif /* REKEY_CHILD_SA_JOB_H_ @} */
index 020c3cce840f8871b577c667001041f40e00d79b..0960f5166435eb404d55b7174dff83c644d09836 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file rekey_ike_sa_job.c
- * 
- * @brief Implementation of rekey_ike_sa_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 "rekey_ike_sa_job.h"
 
 #include <daemon.h>
 
-
 typedef struct private_rekey_ike_sa_job_t private_rekey_ike_sa_job_t;
 
 /**
index 4031b3813cb7149155f7b1234d71ce48e7c52e01..fa45460ccdc38c50a7bec7692bac33b1f9622d31 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file rekey_ike_sa_job.h
- * 
- * @brief Interface of rekey_ike_sa_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 rekey_ike_sa_job rekey_ike_sa_job
+ * @{ @ingroup jobs
  */
 
 #ifndef REKEY_IKE_SA_JOB_H_
@@ -30,14 +30,9 @@ typedef struct rekey_ike_sa_job_t rekey_ike_sa_job_t;
 #include <processing/jobs/job.h>
 
 /**
- * @brief Class representing an REKEY_IKE_SA Job.
+ * Class representing an REKEY_IKE_SA Job.
  * 
  * This job initiates the rekeying of an IKE_SA.
- * 
- * @b Constructors:
- *  - rekey_ike_sa_job_create()
- * 
- * @ingroup jobs
  */
 struct rekey_ike_sa_job_t {
        /**
@@ -47,14 +42,12 @@ struct rekey_ike_sa_job_t {
 };
 
 /**
- * @brief Creates a job of type REKEY_IKE_SA.
+ * Creates a job of type REKEY_IKE_SA.
  *
  * @param ike_sa_id            ID of the IKE_SA to rekey
  * @param reauth               TRUE to reauthenticate peer, FALSE for rekeying only
  * @return                             rekey_ike_sa_job_t object
- * 
- * @ingroup jobs
  */
 rekey_ike_sa_job_t *rekey_ike_sa_job_create(ike_sa_id_t *ike_sa_id, bool reauth);
 
-#endif /* REKEY_IKE_SA_JOB_H_ */
+#endif /* REKEY_IKE_SA_JOB_H_ @} */
index 8c15aa6519186df1071f6603a26f342f3a3013ff..cd765261784da343e353398705bfa22357a86029 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file retransmit_job.c
- * 
- * @brief Implementation of retransmit_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "retransmit_job.h"
index 93bb548e7dcb6940159dba3b466ec20c412e8153..bbacf00944e4874d57b80c13d00733bbe3efc7a9 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file retransmit_job.h
- * 
- * @brief Interface of retransmit_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 retransmit_job retransmit_job
+ * @{ @ingroup jobs
  */
 
 #ifndef RETRANSMIT_JOB_H_
@@ -31,16 +31,11 @@ typedef struct retransmit_job_t retransmit_job_t;
 #include <sa/ike_sa_id.h>
 
 /**
- * @brief Class representing an retransmit Job.
+ * Class representing an retransmit Job.
  *
  * This job is scheduled every time a request is sent over the
  * wire. If the response to the request is not received at schedule
  * time, the retransmission will be initiated.
- *
- * @b Constructors:
- * - retransmit_job_create()
- *
- * @ingroup jobs
  */
 struct retransmit_job_t {
        /**
@@ -50,15 +45,13 @@ struct retransmit_job_t {
 };
 
 /**
- * @brief Creates a job of type retransmit.
+ * Creates a job of type retransmit.
  * 
  * @param message_id           message_id of the request to resend
  * @param ike_sa_id                    identification of the ike_sa as ike_sa_id_t
  * @return                                     retransmit_job_t object
- * 
- * @ingroup jobs
  */
 retransmit_job_t *retransmit_job_create(u_int32_t message_id,
                                                                                ike_sa_id_t *ike_sa_id);
 
-#endif /* RETRANSMIT_JOB_H_ */
+#endif /* RETRANSMIT_JOB_H_ @} */
index 842f5740549562c83f829463d14306abb1b73163..3574b353989e66f56103d82a2a13a3f5bb4c40f1 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file roam_job.c
- * 
- * @brief Implementation of roam_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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>
 
 #include "roam_job.h"
index 293b09f083ce617cfd3d7779124df4c311636f8f..4dafdd532a566bc29c098adf56656d8c481b6f43 100644 (file)
@@ -1,9 +1,3 @@
-/**
- * @file roam_job.h
- * 
- * @brief Interface of roam_job_t.
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 roam_job roam_job
+ * @{ @ingroup jobs
  */
 
 #ifndef ROAM_JOB_H_
@@ -29,15 +30,10 @@ typedef struct roam_job_t roam_job_t;
 #include <processing/jobs/job.h>
 
 /**
- * @brief A job to inform IKE_SAs about changed local address setup.
+ * A job to inform IKE_SAs about changed local address setup.
  * 
  * If a local address appears or disappears, the kernel fires this job to
  * update all IKE_SAs.
- * 
- * @b Constructors:
- * - roam_job_create()
- * 
- * @ingroup jobs
  */
 struct roam_job_t {
 
@@ -48,14 +44,11 @@ struct roam_job_t {
 };
 
 /**
- * @brief Creates a job to inform IKE_SAs about an updated address list.
+ * Creates a job to inform IKE_SAs about an updated address list.
  * 
  * @param address              TRUE if address list changed, FALSE if routing changed
  * @return                             initiate_ike_sa_job_t object
- * 
- * @ingroup jobs
  */
 roam_job_t *roam_job_create(bool address);
 
-#endif /*ROAM_JOB_H_*/
-
+#endif /*ROAM_JOB_H_ @} */
index d9c457ab6fcdaecf9980ef2c060cd39328ed5b50..c74c4c0df9562a64d058a2022599b2d9cede94fb 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file send_dpd_job.c
- * 
- * @brief Implementation of send_dpd_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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>
 
 #include "send_dpd_job.h"
index 0e4059131c8a51e28c8c182a4af2a8a29250659b..73aa720b385bfbf84f6db27538a7101c49f1ef2e 100644 (file)
@@ -1,9 +1,3 @@
-/**
- * @file send_dpd_job.h
- * 
- * @brief Interface of send_dpd_job_t.
- */
-
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 send_dpd_job send_dpd_job
+ * @{ @ingroup jobs
  */
 
 #ifndef SEND_DPD_JOB_H_
@@ -29,16 +30,11 @@ typedef struct send_dpd_job_t send_dpd_job_t;
 #include <sa/ike_sa_id.h>
 
 /**
- * @brief Class representing a SEND_DPD Job.
+ * Class representing a SEND_DPD Job.
  * 
  * Job to periodically send a Dead Peer Detection (DPD) request,
  * ie. an IKE request with no payloads other than the encrypted payload
  * required by the syntax.
- * 
- * @b Constructors:
- * - send_dpd_job_create()
- * 
- * @ingroup jobs
  */
 struct send_dpd_job_t {
        /**
@@ -48,13 +44,11 @@ struct send_dpd_job_t {
 };
 
 /**
- * @brief Creates a job of type SEND_DPD.
+ * Creates a job of type SEND_DPD.
  * 
  * @param ike_sa_id            identification of the ike_sa as ike_sa_id_t object (gets cloned)
  * @return                             initiate_ike_sa_job_t object
- * 
- * @ingroup jobs
  */
 send_dpd_job_t *send_dpd_job_create(ike_sa_id_t *ike_sa_id);
 
-#endif /*SEND_DPD_JOB_H_*/
+#endif /*SEND_DPD_JOB_H_ @} */
index 34198deb0cc5e8ea66058f7a1074a3262d20e530..04408de7643575af99b3e3fd568d98d266976e24 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file send_keepalive_job.c
- * 
- * @brief Implementation of send_keepalive_job_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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>
 
 #include "send_keepalive_job.h"
index e8d214aedcb6ac6fb32b9bd6de947952298e0173..e3bb9f9e4fde2a080f702746c5b7a8b768bdd1a8 100644 (file)
@@ -1,9 +1,3 @@
-/**
- * @file send_keepalive_job.h
- * 
- * @brief Interface of send_keepalive_job_t.
- */
-
 /*
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 send_keepalive_job send_keepalive_job
+ * @{ @ingroup jobs
  */
 
 #ifndef SEND_KEEPALIVE_JOB_H_
@@ -29,15 +30,10 @@ typedef struct send_keepalive_job_t send_keepalive_job_t;
 #include <sa/ike_sa_id.h>
 
 /**
- * @brief Class representing a SEND_KEEPALIVE Job.
+ * Class representing a SEND_KEEPALIVE Job.
  * 
  * This job will send a NAT keepalive packet if the IKE SA is still alive,
  * and reinsert itself into the event queue.
- * 
- * @b Constructors:
- * - send_keepalive_job_create()
- * 
- * @ingroup jobs
  */
 struct send_keepalive_job_t {
        /**
@@ -47,13 +43,11 @@ struct send_keepalive_job_t {
 };
 
 /**
- * @brief Creates a job of type SEND_KEEPALIVE.
+ * Creates a job of type SEND_KEEPALIVE.
  * 
  * @param ike_sa_id            identification of the ike_sa as ike_sa_id_t object (gets cloned)
  * @return                             initiate_ike_sa_job_t object
- * 
- * @ingroup jobs
  */
 send_keepalive_job_t *send_keepalive_job_create(ike_sa_id_t *ike_sa_id);
 
-#endif /*SEND_KEEPALIVE_JOB_H_*/
+#endif /*SEND_KEEPALIVE_JOB_H_ @} */
index b3815eeb18b16c77a92aeabf31f58a40e0c30cc7..bfae7bdfffb4d6ade77871639f8164fea4011d3e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file processor.c
- *
- * @brief Implementation of processor_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
@@ -35,7 +30,7 @@
 typedef struct private_processor_t private_processor_t;
 
 /**
- * @brief Private data of processor_t class.
+ * Private data of processor_t class.
  */
 struct private_processor_t {
        /**
index f12c7f10e53225661bbc50b63d6fa5f9754a2b62..342cfa048f8bcb4dc7c242abc0ea891691ff102f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file processor.h
- * 
- * @brief Interface of processor_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 processor processor
+ * @{ @ingroup processing
  */
 
 #ifndef PROCESSOR_H_
@@ -32,80 +32,65 @@ typedef struct processor_t processor_t;
 #include <processing/jobs/job.h>
 
 /**
- * @brief The processor uses threads to process queued jobs.
- *
- * @b Constructors:
- *  - processor_create()
- * 
- * @ingroup processing
+ * The processor uses threads to process queued jobs.
  */
 struct processor_t {
        
        /**
-        * @brief Get the total number of threads used by the processor.
-        *
-        * @param this                  calling object          
+        * Get the total number of threads used by the processor.
+        *      
         * @return                              size of thread pool
         */
        u_int (*get_total_threads) (processor_t *this);
        
        /**
-        * @brief Get the number of threads currently waiting.
-        *
-        * @param this                  calling object          
+        * Get the number of threads currently waiting.
+        *      
         * @return                              number of idle threads
         */
        u_int (*get_idle_threads) (processor_t *this);
        
        /**
-        * @brief Get the number of queued jobs.
+        * Get the number of queued jobs.
         *
-        * @param this                  calling object
         * @returns                     number of items in queue
         */
        u_int (*get_job_load) (processor_t *this);
 
        /**
-        * @brief Adds a job to the queue.
+        * Adds a job to the queue.
         *
         * This function is non blocking and adds a job_t to the queue.
         *
-        * @param this                  calling object
         * @param job                   job to add to the queue
         */
        void (*queue_job) (processor_t *this, job_t *job);
        
        /**
-        * @brief Set the number of threads to use in the processor.
+        * Set the number of threads to use in the processor.
         *
         * If the number of threads is smaller than number of currently running
         * threads, thread count is decreased. Use 0 to disable the processor.
         * This call blocks if it decreases thread count until threads have
         * terminated, so make sure there are not too many blocking jobs.
         *
-        * @param this                  calling object
         * @param count                 number of threads to allocate
         */
        void (*set_threads)(processor_t *this, u_int count);
        
        /**
-        * @brief Destroy a processor object.
-        * 
-        * @param processor     calling object
+        * Destroy a processor object.
         */
        void (*destroy) (processor_t *processor);
 };
 
 /**
- * @brief Create the thread pool without any threads.
+ * Create the thread pool without any threads.
  *
  * Use the set_threads method to start processing jobs.
  *
  * @return                                     processor_t object
- *
- * @ingroup processing
  */
 processor_t *processor_create();
 
-#endif /*PROCESSOR_H_*/
-
+#endif /*PROCESSOR_H_ @} */
index ededb479acab832487789e4ebd99f52f23861957..bbf1dc1a4b9608f6786e7f24612a9f14bab5be5a 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file scheduler.c
- *
- * @brief Implementation of scheduler_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
index 7bde6e63860ec34ea20f7b74cf18efc738916309..441f053cfa88d1c1baf8d764afb6b86f2d552dc3 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file scheduler.h
- * 
- * @brief Interface of scheduler_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 scheduler scheduler
+ * @{ @ingroup processing
  */
 
 #ifndef SCHEDULER_H_
@@ -30,52 +30,40 @@ typedef struct scheduler_t scheduler_t;
 #include <processing/jobs/job.h>
 
 /**
- * @brief The scheduler queues and executes timed events.
+ * The scheduler queues and executes timed events.
  *
  * The scheduler stores timed events and passes them to the processor.
- *
- * @b Constructors:
- *  - scheduler_create()
- *
- * @ingroup processing
  */
 struct scheduler_t {   
 
        /**
-        * @brief Adds a event to the queue, using a relative time offset.
+        * Adds a event to the queue, using a relative time offset.
         *
         * Schedules a job for execution using a relative time offset.
         *
-        * @param this                  calling object
         * @param job                   job to schedule
         * @param time                  relative to to schedule job (in ms)
         */
        void (*schedule_job) (scheduler_t *this, job_t *job, u_int32_t time);
        
        /**
-        * @brief Returns number of jobs scheduled.
+        * Returns number of jobs scheduled.
         *
-        * @param this                  calling object
         * @return                              number of scheduled jobs
         */
        u_int (*get_job_load) (scheduler_t *this);
        
        /**
-        * @brief Destroys a scheduler object.
-        * 
-        * @param this                  calling object
+        * Destroys a scheduler object.
         */
        void (*destroy) (scheduler_t *this);
 };
 
 /**
- * @brief Create a scheduler.
+ * Create a scheduler.
  * 
  * @return             scheduler_t object
- * 
- * @ingroup processing
  */
 scheduler_t *scheduler_create(void);
 
-#endif /*SCHEDULER_H_*/
-
+#endif /*SCHEDULER_H_ @} */
index 707aae9ad8a47965884e0829650c8a02528c805d..fc528ff5408abb86d41679a912d8d420195e2b15 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file authenticator.c
- *
- * @brief Generic constructor for authenticators.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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>
index c7b0fc81a3bbcfaaf60fbb5c9462cad4c703f9db..d0286be3e6642a3aea30cd78c397cf76cdd0959d 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file authenticator.h
- *
- * @brief Interface of authenticator_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 authenticator authenticator
+ * @{ @ingroup authenticators
  */
 
 #ifndef AUTHENTICATOR_H_
@@ -33,8 +33,6 @@ typedef struct authenticator_t authenticator_t;
 
 /**
  * Method to use for authentication.
- *
- * @ingroup authenticators
  */
 enum auth_method_t {
        /**
@@ -65,29 +63,21 @@ enum auth_method_t {
 
 /**
  * enum names for auth_method_t.
- *
- * @ingroup authenticators
  */
 extern enum_name_t *auth_method_names;
 
 /**
- * @brief Authenticator interface implemented by the various authenticators.
+ * Authenticator interface implemented by the various authenticators.
  *
  * Currently the following two AUTH methods are supported:
  *  - shared key message integrity code (AUTH_PSK)
  *  - RSA digital signature (AUTH_RSA)
- *
- * @b Constructors:
- *  - authenticator_create()
- *
- * @ingroup authenticators
  */
 struct authenticator_t {
 
        /**
-        * @brief Verify a received authentication payload.
+        * Verify a received authentication payload.
         *
-        * @param this                          calling object
         * @param ike_sa_init           binary representation of received ike_sa_init
         * @param my_nonce                      the sent nonce
         * @param auth_payload          authentication payload to verify
@@ -102,9 +92,8 @@ struct authenticator_t {
                                                chunk_t my_nonce, auth_payload_t *auth_payload);
 
        /**
-        * @brief Build an authentication payload to send to the other peer.
+        * Build an authentication payload to send to the other peer.
         *
-        * @param this                          calling object
         * @param ike_sa_init           binary representation of sent ike_sa_init
         * @param other_nonce           the received nonce
         * @param[out] auth_payload     the resulting authentication payload
@@ -117,23 +106,19 @@ struct authenticator_t {
                                           chunk_t other_nonce, auth_payload_t **auth_payload);
 
        /**
-        * @brief Destroys a authenticator_t object.
-        *
-        * @param this                          calling object
+        * Destroys a authenticator_t object.
         */
        void (*destroy) (authenticator_t *this);
 };
 
 /**
- * @brief Creates an authenticator for the specified auth method.
+ * Creates an authenticator for the specified auth method.
  *
  * @param ike_sa               associated ike_sa
  * @param auth_method  authentication method to use for build()/verify()
  *
  * @return                             authenticator_t object
- *
- * @ingroup authenticators
  */
 authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_method);
 
-#endif /* AUTHENTICATOR_H_ */
+#endif /* AUTHENTICATOR_H_ @} */
diff --git a/src/charon/sa/authenticators/eap/eap_manager.c b/src/charon/sa/authenticators/eap/eap_manager.c
new file mode 100644 (file)
index 0000000..8a4d4ee
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "eap_manager.h"
+
+#include <pthread.h>
+
+#include <utils/linked_list.h>
+
+typedef struct private_eap_manager_t private_eap_manager_t;
+typedef struct eap_entry_t eap_entry_t;
+
+/**
+ * EAP constructor entry
+ */
+struct eap_entry_t {
+       
+       /**
+        * EAP method type, vendor specific if vendor is set
+        */
+       eap_type_t type;
+       
+       /**
+        * vendor ID, 0 for default EAP methods
+        */
+       u_int32_t vendor;
+       
+       /**
+        * Role of the method returned by the constructor, EAP_SERVER or EAP_PEER
+        */
+       eap_role_t role;
+       
+       /**
+        * constructor function to create instance
+        */
+       eap_constructor_t constructor;
+};
+
+/**
+ * private data of eap_manager
+ */
+struct private_eap_manager_t {
+
+       /**
+        * public functions
+        */
+       eap_manager_t public;
+       
+       /**
+        * list of eap_entry_t's
+        */
+       linked_list_t *methods;
+       
+       /**
+        * mutex to lock methods
+        */
+       pthread_mutex_t mutex;
+};
+
+/**
+ * Implementation of eap_manager_t.add_method.
+ */
+static void add_method(private_eap_manager_t *this, eap_type_t type,
+                                          u_int32_t vendor, eap_role_t role,
+                                          eap_constructor_t constructor)
+{
+       eap_entry_t *entry = malloc_thing(eap_entry_t);
+       
+       entry->type = type;
+       entry->vendor = vendor;
+       entry->role = role;
+       entry->constructor = constructor;
+
+       pthread_mutex_lock(&this->mutex);
+       this->methods->insert_last(this->methods, entry);
+       pthread_mutex_unlock(&this->mutex);
+}
+
+/**
+ * Implementation of eap_manager_t.remove_method.
+ */
+static void remove_method(private_eap_manager_t *this, eap_constructor_t constructor)
+{
+       enumerator_t *enumerator;
+       eap_entry_t *entry;
+       
+       pthread_mutex_lock(&this->mutex);
+       enumerator = this->methods->create_enumerator(this->methods);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (constructor == entry->constructor)
+               {
+                       this->methods->remove_at(this->methods, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       pthread_mutex_unlock(&this->mutex);
+}
+
+/**
+ * Implementation of eap_manager_t.create_instance.
+ */
+static eap_method_t* create_instance(private_eap_manager_t *this,
+                                                                        eap_type_t type, u_int32_t vendor,
+                                                                        eap_role_t role, identification_t *server,
+                                                                        identification_t *peer)
+{
+       enumerator_t *enumerator;
+       eap_entry_t *entry;
+       eap_method_t *method = NULL;
+       
+       pthread_mutex_lock(&this->mutex);
+       enumerator = this->methods->create_enumerator(this->methods);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (type == entry->type && vendor == entry->vendor &&
+                       role == entry->role)
+               {
+                       method = entry->constructor(server, peer);
+                       if (method)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       pthread_mutex_unlock(&this->mutex);
+       return method;
+}
+
+/**
+ * Implementation of 2008_t.destroy
+ */
+static void destroy(private_eap_manager_t *this)
+{
+       this->methods->destroy_function(this->methods, free);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+eap_manager_t *eap_manager_create()
+{
+       private_eap_manager_t *this = malloc_thing(private_eap_manager_t);
+       
+       this->public.add_method = (void(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, eap_constructor_t constructor))add_method;
+       this->public.remove_method = (void(*)(eap_manager_t*, eap_constructor_t constructor))remove_method;
+       this->public.create_instance = (eap_method_t*(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, identification_t*,identification_t*))create_instance;
+       this->public.destroy = (void(*)(eap_manager_t*))destroy;
+       
+       this->methods = linked_list_create();
+       pthread_mutex_init(&this->mutex, NULL);
+       
+       return &this->public;
+}
+
diff --git a/src/charon/sa/authenticators/eap/eap_manager.h b/src/charon/sa/authenticators/eap/eap_manager.h
new file mode 100644 (file)
index 0000000..2737345
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup eap_manager eap_manager
+ * @{ @ingroup eap
+ */
+
+#ifndef EAP_MANAGER_H_
+#define EAP_MANAGER_H_
+
+#include <sa/authenticators/eap/eap_method.h>
+
+typedef struct eap_manager_t eap_manager_t;
+
+/**
+ * The EAP manager manages all EAP implementations and creates instances.
+ *
+ * A plugin registers it's implemented EAP method at the manager by
+ * providing type and a contructor function. The manager then instanciates
+ * eap_method_t instances through the provided constructor to handle
+ * EAP authentication.
+ */
+struct eap_manager_t {
+
+       /**
+        * Register a EAP method implementation.
+        *
+        * @param method                vendor specific method, if vendor != 0
+        * @param vendor                vendor ID, 0 for non-vendor (default) EAP methods
+        * @param role                  EAP role of the registered method
+        * @param constructor   constructor function, returns an eap_method_t
+        */
+       void (*add_method)(eap_manager_t *this, eap_type_t type, u_int32_t vendor,
+                                          eap_role_t role, eap_constructor_t constructor);
+       
+       /**
+        * Unregister a EAP method implementation using it's constructor.
+        *
+        * @param constructor   constructor function to remove, as added in add_method
+        */
+       void (*remove_method)(eap_manager_t *this, eap_constructor_t constructor);
+       
+       /**
+        * Create a new EAP method instance.
+        *
+        * @param type                  type of the EAP method
+        * @param vendor                vendor ID, 0 for non-vendor (default) EAP methods
+        * @param role                  role of EAP method, either EAP_SERVER or EAP_PEER
+        * @param server                identity of the server
+        * @param peer                  identity of the peer (client)
+        * @return                              EAP method instance, NULL if no constructor found
+        */
+       eap_method_t* (*create_instance)(eap_manager_t *this, eap_type_t type,
+                                                                        u_int32_t vendor, eap_role_t role,
+                                                                        identification_t *server,
+                                                                        identification_t *peer);
+       
+       /**
+     * Destroy a eap_manager instance.
+     */
+    void (*destroy)(eap_manager_t *this);
+};
+
+/**
+ * Create a eap_manager instance.
+ */
+eap_manager_t *eap_manager_create();
+
+#endif /* EAP_MANAGER_H_ @}*/
index 7434ca2a1c78c16fd860e940f9c66175e4f98cb9..a9f7abda06a5436a9d3f66c41ce7f5da99ae4878 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_method.c
- *
- * @brief Generic constructor for eap_methods.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <error.h>
-#include <dlfcn.h>
-
 #include "eap_method.h"
 
-#include <daemon.h>
-#include <library.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-
 ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_TOKEN_CARD,
        "EAP_IDENTITY",
        "EAP_NOTIFICATION",
@@ -62,171 +45,3 @@ ENUM(eap_role_names, EAP_SERVER, EAP_PEER,
        "EAP_PEER",
 );
 
-
-typedef struct module_entry_t module_entry_t;
-
-/**
- * Representation of a loaded module: EAP type, library handle, constructor
- */
-struct module_entry_t {
-       eap_type_t type;
-       u_int32_t vendor;
-       void *handle;
-       eap_constructor_t constructor;
-};
-
-/** List of module_entry_t's */
-static linked_list_t *modules = NULL;
-
-/**
- * unload modules at daemon shutdown
- */
-void eap_method_unload()
-{
-       if (modules)
-       {
-               module_entry_t *entry;
-               
-               while (modules->remove_last(modules, (void**)&entry) == SUCCESS)
-               {
-                       DBG2(DBG_CFG, "unloaded module EAP module %d-%d",
-                                entry->type, entry->vendor);
-                       dlclose(entry->handle);
-                       free(entry);
-               }
-               modules->destroy(modules);
-               modules = NULL;
-       }
-}
-
-/**
- * Load EAP modules at daemon startup
- */
-void eap_method_load(char *directory)
-{
-       struct dirent* entry;
-       DIR* dir;
-       
-       eap_method_unload();    
-       modules = linked_list_create();
-
-       dir = opendir(directory);
-       if (dir == NULL)
-       {
-               DBG1(DBG_CFG, "error opening EAP modules directory %s", directory);
-               return;
-       }
-       
-       DBG1(DBG_CFG, "loading EAP modules from '%s'", directory);
-
-       while ((entry = readdir(dir)) != NULL)
-       {
-               char file[256];
-               module_entry_t module, *loaded_module;
-               eap_method_t *method;
-               identification_t *id;
-               char *ending;
-               
-               snprintf(file, sizeof(file), "%s/%s", directory, entry->d_name);
-               
-               ending = entry->d_name + strlen(entry->d_name) - 3;
-               if (ending <= entry->d_name || !streq(ending, ".so"))
-               {
-                       /* skip anything which does not look like a library */
-                       DBG2(DBG_CFG, "  skipping %s, doesn't look like a library",
-                                entry->d_name);
-                       continue;
-               }
-               
-               /* try to load the library */
-               module.handle = dlopen(file, RTLD_LAZY);
-               if (module.handle == NULL)
-               {
-                       DBG1(DBG_CFG, "  opening EAP module %s failed: %s", entry->d_name,
-                                dlerror());
-                       continue;
-               }
-               module.constructor = dlsym(module.handle, "eap_create");
-               if (module.constructor == NULL)
-               {
-                       DBG1(DBG_CFG, "  EAP module %s has no eap_create() function, skipped",
-                               entry->d_name);
-                       dlclose(module.handle);
-                       continue;
-               }
-               
-               /* get the type implemented in the method, create an instance for it */
-               id = identification_create_from_string("john@doe.xyz");
-               method = module.constructor(EAP_SERVER, id, id);
-               if (method == NULL)
-               {
-                       method = module.constructor(EAP_PEER, id, id);
-               }
-               id->destroy(id);
-               if (method == NULL)
-               {
-                       DBG1(DBG_CFG, "  unable to create instance of EAP method %s, skipped",
-                                entry->d_name);
-                       dlclose(module.handle);
-                       continue;
-               }
-               module.type = method->get_type(method, &module.vendor);
-               method->destroy(method);
-               
-               if (module.vendor)
-               {       
-                       DBG1(DBG_CFG, "  loaded EAP method %d, vendor %d successfully from %s",
-                                module.type, module.vendor, entry->d_name);
-               }
-               else
-               {
-                       DBG1(DBG_CFG, "  loaded EAP method %N successfully from %s",
-                                eap_type_names, module.type, entry->d_name);
-               }
-                        
-               loaded_module = malloc_thing(module_entry_t);
-               memcpy(loaded_module, &module, sizeof(module));
-               modules->insert_last(modules, loaded_module);
-       }
-       closedir(dir);
-}
-
-/*
- * Described in header.
- */
-eap_method_t *eap_method_create(eap_type_t type, u_int32_t vendor, eap_role_t role,
-                                                               identification_t *server, identification_t *peer)
-{
-       eap_method_t *method = NULL;
-       iterator_t *iterator;
-       module_entry_t *entry;
-       
-       iterator = modules->create_iterator(modules, TRUE);
-       while (iterator->iterate(iterator, (void**)&entry))
-       {
-               if (entry->type == type && entry->vendor == vendor)
-               {
-                       method = entry->constructor(role, server, peer);
-                       if (method)
-                       {
-                               break;
-                       }
-               }
-       }
-       iterator->destroy(iterator);
-       
-       if (method == NULL)
-       {
-               if (vendor)
-               {
-                       DBG1(DBG_CFG, "no vendor %d specific EAP module found for method "
-                                "%d %N", vendor, type, eap_role_names, role);
-               }
-               else
-               {
-                       DBG1(DBG_CFG, "no EAP module found for %N %N",
-                                eap_type_names, type, eap_role_names, role);
-               }
-       }
-       return method;
-}
index 8675fd8ece22a2d2e6a0636bcf0f003c1db11bd4..ca7b368002004b7c7ebf0c1841ad148b902b1550 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_method.h
- *
- * @brief Interface eap_method_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 eap_method eap_method
+ * @{ @ingroup eap
  */
 
 #ifndef EAP_METHOD_H_
@@ -34,8 +34,6 @@ typedef enum eap_code_t eap_code_t;
 
 /**
  * Role of an eap_method, SERVER or PEER (client)
- *
- * @ingroup eap
  */
 enum eap_role_t {
        EAP_SERVER,
@@ -43,15 +41,11 @@ enum eap_role_t {
 };
 /**
  * enum names for eap_role_t.
- *
- * @ingroup eap
  */
 extern enum_name_t *eap_role_names;
 
 /**
  * EAP types, defines the EAP method implementation
- *
- * @ingroup eap
  */
 enum eap_type_t {
        EAP_IDENTITY = 1,
@@ -68,15 +62,11 @@ enum eap_type_t {
 
 /**
  * enum names for eap_type_t.
- *
- * @ingroup eap
  */
 extern enum_name_t *eap_type_names;
 
 /**
  * EAP code, type of an EAP message
- *
- * @ingroup eap
  */
 enum eap_code_t {
        EAP_REQUEST = 1,
@@ -87,14 +77,12 @@ enum eap_code_t {
 
 /**
  * enum names for eap_code_t.
- *
- * @ingroup eap
  */
 extern enum_name_t *eap_code_names;
 
 
 /**
- * @brief Interface of an EAP method for server and client side.
+ * Interface of an EAP method for server and client side.
  *
  * An EAP method initiates an EAP exchange and processes requests and
  * responses. An EAP method may need multiple exchanges before succeeding, and
@@ -107,22 +95,16 @@ extern enum_name_t *eap_code_names;
  * authentication. Even if a mutual EAP method is used, the traditional
  * AUTH payloads are required. Only these include the nonces and messages from
  * ike_sa_init and therefore prevent man in the middle attacks.
- *
- * @b Constructors:
- *  - eap_method_create()
- *
- * @ingroup eap
  */
 struct eap_method_t {
        
        /**
-        * @brief Initiate the EAP exchange.
+        * Initiate the EAP exchange.
         *
         * initiate() is only useable for server implementations, as clients only
         * reply to server requests.
         * A eap_payload is created in "out" if result is NEED_MORE.
         *
-        * @param this          calling object
         * @param out           eap_payload to send to the client
         * @return
         *                                      - NEED_MORE, if an other exchange is required
@@ -131,11 +113,10 @@ struct eap_method_t {
        status_t (*initiate) (eap_method_t *this, eap_payload_t **out);
        
        /**
-        * @brief Process a received EAP message.
+        * Process a received EAP message.
         *
         * A eap_payload is created in "out" if result is NEED_MORE.
         *
-        * @param this          calling object
         * @param in            eap_payload response received
         * @param out           created eap_payload to send
         * @return
@@ -147,31 +128,28 @@ struct eap_method_t {
                                                 eap_payload_t **out);
        
        /**
-        * @brief Get the EAP type implemented in this method.
+        * Get the EAP type implemented in this method.
         *
-        * @param this          calling object
         * @param vendor        pointer receiving vendor identifier for type, 0 for none
         * @return                      type of the EAP method
         */
        eap_type_t (*get_type) (eap_method_t *this, u_int32_t *vendor);
        
        /**
-        * @brief Check if this EAP method authenticates the server.
+        * Check if this EAP method authenticates the server.
         *
         * Some EAP methods provide mutual authentication and 
         * allow authentication using only EAP, if the peer supports it.
         *
-        * @param this          calling object
         * @return                      TRUE if methods provides mutual authentication
         */
        bool (*is_mutual) (eap_method_t *this);
        
        /**
-        * @brief Get the MSK established by this EAP method.
+        * Get the MSK established by this EAP method.
         *
         * Not all EAP methods establish a shared secret.
         *
-        * @param this          calling object
         * @param msk           chunk receiving internal stored MSK
         * @return
         *                                      - SUCCESS, or
@@ -180,68 +158,25 @@ struct eap_method_t {
        status_t (*get_msk) (eap_method_t *this, chunk_t *msk);
        
        /**
-        * @brief Destroys a eap_method_t object.
-        *
-        * @param this                          calling object
+        * Destroys a eap_method_t object.
         */
        void (*destroy) (eap_method_t *this);
 };
 
 /**
- * @brief Creates an EAP method for a specific type and role.
- *
- * @param eap_type             EAP type to use
- * @param eap_vendor   vendor identifier if a vendor specifc EAP type is used
- * @param role                 role of the eap_method, server or peer
- * @param server               ID of acting server
- * @param peer                 ID of involved peer (client)
- * @return                             eap_method_t object
- *
- * @ingroup eap
- */
-eap_method_t *eap_method_create(eap_type_t eap_type, u_int32_t eap_vendor,
-                                                               eap_role_t role, identification_t *server,
-                                                               identification_t *peer);
-
-/**
- * @brief (Re-)Load all EAP modules in the EAP modules directory.
- *
- * For security reasons, the directory and all it's modules must be owned
- * by root and must not be writeable by someone else.
- *
- * @param dir                  directory of the EAP modules
- *
- * @ingroup eap
- */
-void eap_method_load(char *directory);
-
-/**
- * @brief Unload all loaded EAP modules
- *
- * @ingroup eap
- */
-void eap_method_unload();
-
-/**
- * @brief Constructor definition for a pluggable EAP module.
+ * Constructor definition for a pluggable EAP method.
  *
  * Each EAP module must define a constructor function which will return
- * an initialized object with the methods defined in eap_method_t. The
- * constructor must be named eap_create() and it's signature must be equal
- * to that of eap_constructor_t.
- * A module may implement only a single role. If it does not support the role
- * requested, NULL should be returned. Multiple modules are allowed of the
- * same EAP type to support seperate implementations of peer/server.
+ * an initialized object with the methods defined in eap_method_t.
+ * Constructors for server and peers are identical, to support both roles
+ * of a EAP method, a plugin needs register two constructors in the
+ * eap_manager_t.
  *
- * @param role                 role the module will play, peer or server
  * @param server               ID of the server to use for credential lookup
  * @param peer                 ID of the peer to use for credential lookup
  * @return                             implementation of the eap_method_t interface
- *
- * @ingroup eap
  */
-typedef eap_method_t *(*eap_constructor_t)(eap_role_t role,
-                                                                                  identification_t *server,
+typedef eap_method_t *(*eap_constructor_t)(identification_t *server,
                                                                                   identification_t *peer);
 
-#endif /* EAP_METHOD_H_ */
+#endif /* EAP_METHOD_H_ @} */
index edd75da436c9b241a7fb1224d4af66b4410eba43..195853626b94422077c4cecb233572e82c398120 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_authenticator.c
- *
- * @brief Implementation of eap_authenticator_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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>
@@ -160,9 +155,9 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
        {
                DBG1(DBG_IKE, "requesting %N authentication", eap_type_names, type);
        }
-       this->method = eap_method_create(type, vendor, this->role,
-                                                                        this->ike_sa->get_my_id(this->ike_sa),
-                                                                        this->ike_sa->get_other_id(this->ike_sa));
+       this->method = charon->eap->create_instance(charon->eap, type, vendor,
+                                               this->role, this->ike_sa->get_my_id(this->ike_sa),
+                                               this->ike_sa->get_other_id(this->ike_sa));
        
        if (this->method == NULL)
        {
@@ -195,9 +190,11 @@ static status_t process_peer(private_eap_authenticator_t *this,
        
        if (!vendor && type == EAP_IDENTITY)
        {
-               eap_method_t *method = eap_method_create(type, 0, EAP_PEER,
-                                                                          this->ike_sa->get_other_id(this->ike_sa),
-                                                                          this->ike_sa->get_my_id(this->ike_sa));
+               eap_method_t *method;
+               
+               method = charon->eap->create_instance(charon->eap, type, 0, EAP_PEER,
+                                                                       this->ike_sa->get_other_id(this->ike_sa),
+                                                                       this->ike_sa->get_my_id(this->ike_sa));
                
                if (method == NULL || method->process(method, in, out) != SUCCESS)
                {
@@ -227,9 +224,10 @@ static status_t process_peer(private_eap_authenticator_t *this,
                        DBG1(DBG_IKE, "EAP server requested %N authentication",
                                 eap_type_names, type);
                }
-               this->method = eap_method_create(type, vendor, EAP_PEER,
-                                                       this->ike_sa->get_other_id(this->ike_sa),
-                                                       this->ike_sa->get_my_id(this->ike_sa));
+               this->method = charon->eap->create_instance(charon->eap,
+                                                                       type, vendor, EAP_PEER,
+                                                                       this->ike_sa->get_other_id(this->ike_sa),
+                                                                       this->ike_sa->get_my_id(this->ike_sa));
                if (this->method == NULL)
                {
                        DBG1(DBG_IKE, "EAP server requested unsupported "
index cf2180ee3db9c7da32d183601f9c203791d7e719..717ee9f4cee8fb2f71abe2b8b11dd112a811dc56 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file eap_authenticator.h
- *
- * @brief Interface of eap_authenticator_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 eap_authenticator eap_authenticator
+ * @{ @ingroup authenticators
  */
 
 #ifndef EAP_AUTHENTICATOR_H_
@@ -29,7 +29,7 @@ typedef struct eap_authenticator_t eap_authenticator_t;
 #include <encoding/payloads/eap_payload.h>
 
 /**
- * @brief Implementation of the authenticator_t interface using AUTH_EAP.
+ * Implementation of the authenticator_t interface using AUTH_EAP.
  *
  * Authentication using EAP involves the most complex authenticator. It stays
  * alive over multiple ike_auth transactions and handles multiple EAP
@@ -68,11 +68,6 @@ typedef struct eap_authenticator_t eap_authenticator_t;
      +--------+                                +--------+
 
    @endverbatim
- * @b Constructors:
- *  - eap_authenticator_create()
- *  - authenticator_create() using auth_method AUTH_EAP
- *
- * @ingroup authenticators
  */
 struct eap_authenticator_t {
 
@@ -82,7 +77,7 @@ struct eap_authenticator_t {
        authenticator_t authenticator_interface;
        
        /**
-        * @brief Check if the EAP method was/is mutual and secure.
+        * 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
@@ -93,19 +88,17 @@ struct eap_authenticator_t {
         * AUTH payload, the client must verify that the server initiated mutual
         * EAP authentication before it can trust the server.
         *
-        * @param this  calling object
         * @return              TRUE, if no AUTH payload required, FALSE otherwise
         */
        bool (*is_mutual) (eap_authenticator_t* this);
        
        /**
-        * @brief Initiate the EAP exchange.
+        * 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 this          calling object
         * @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
@@ -117,7 +110,7 @@ struct eap_authenticator_t {
                                                  u_int32_t vendor, eap_payload_t **out);
        
        /**
-        * @brief Process an EAP message.
+        * Process an EAP message.
         *
         * After receiving an EAP message "in", the peer/server processes
         * the payload and creates a reply/subsequent request.
@@ -132,7 +125,6 @@ struct eap_authenticator_t {
         * If a SUCCESS is returned (on any side), the EAP authentication was
         * successful and the AUTH payload can be exchanged.
         *
-        * @param this  calling object
         * @param in    received EAP message
         * @param out   created EAP message to send
         * @return
@@ -145,13 +137,11 @@ struct eap_authenticator_t {
 };
 
 /**
- * @brief Creates an authenticator for AUTH_EAP.
+ * Creates an authenticator for AUTH_EAP.
  *
  * @param ike_sa               associated ike_sa
  * @return                             eap_authenticator_t object
- *
- * @ingroup authenticators
  */
 eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa);
 
-#endif /* EAP_AUTHENTICATOR_H_ */
+#endif /* EAP_AUTHENTICATOR_H_ @} */
index 6b76088bb76a6731f32c431e0094f417a322ff48..9094077e4e0f1e88d5c40e31aba93dd0bd7759c1 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file psk_authenticator.c
- *
- * @brief Implementation of psk_authenticator_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
@@ -26,6 +21,7 @@
 #include "psk_authenticator.h"
 
 #include <daemon.h>
+#include <credentials/auth_info.h>
 
 /**
  * Key pad for the AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
@@ -105,39 +101,49 @@ chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce,
  * Implementation of authenticator_t.verify.
  */
 static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
-                               chunk_t my_nonce, auth_payload_t *auth_payload)
+                                          chunk_t my_nonce, auth_payload_t *auth_payload)
 {
-       status_t status;
-       chunk_t auth_data, recv_auth_data, shared_key;
+       chunk_t auth_data, recv_auth_data;
        identification_t *my_id, *other_id;
+       shared_key_t *shared_key;
+       enumerator_t *enumerator;
+       bool authenticated = FALSE;
+       int keys_found = 0;
        
        my_id = this->ike_sa->get_my_id(this->ike_sa);
        other_id = this->ike_sa->get_other_id(this->ike_sa);
-       status = charon->credentials->get_shared_key(charon->credentials, my_id,
-                                                                                                other_id, &shared_key);
-       if (status != SUCCESS)
+       enumerator = charon->credentials->create_shared_enumerator(
+                                                       charon->credentials, SHARED_IKE, my_id, other_id);
+       while (!authenticated && enumerator->enumerate(enumerator, &shared_key, NULL, NULL))
        {
-               DBG1(DBG_IKE, "no shared key found for '%D' - '%D'",  my_id, other_id);
-               return status;
+               keys_found++;
+               auth_data = build_shared_key_signature(ike_sa_init, my_nonce,
+                                                                       shared_key->get_key(shared_key), other_id,
+                                                                       this->ike_sa->get_skp_verify(this->ike_sa),
+                                                                       this->ike_sa->get_prf(this->ike_sa));
+               recv_auth_data = auth_payload->get_data(auth_payload);
+               if (auth_data.len == recv_auth_data.len &&
+                       memeq(auth_data.ptr, recv_auth_data.ptr, auth_data.len))
+               {
+                       DBG1(DBG_IKE, "authentication of '%D' with %N successful",
+                                other_id, auth_method_names, AUTH_PSK);
+                       authenticated = TRUE;
+               }
+               chunk_free(&auth_data);
        }
+       enumerator->destroy(enumerator);
        
-       auth_data = build_shared_key_signature(ike_sa_init, my_nonce, shared_key,
-                                               other_id, this->ike_sa->get_skp_verify(this->ike_sa),
-                                               this->ike_sa->get_prf(this->ike_sa));
-       chunk_free_randomized(&shared_key);
-       
-       recv_auth_data = auth_payload->get_data(auth_payload);
-       if (auth_data.len != recv_auth_data.len ||
-               !memeq(auth_data.ptr, recv_auth_data.ptr, auth_data.len))
+       if (!authenticated)
        {
-               DBG1(DBG_IKE, "PSK MAC verification failed");
-               chunk_free(&auth_data);
+               if (keys_found == 0)
+               {
+                       DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
+                       return NOT_FOUND;
+               }
+               DBG1(DBG_IKE, "tried %d shared key%s for '%D' - '%D', but MAC mismatched",
+                        keys_found, keys_found == 1 ? "" : "s", my_id, other_id);
                return FAILED;
        }
-       chunk_free(&auth_data);
-       
-       DBG1(DBG_IKE, "authentication of '%D' with %N successful",
-                other_id, auth_method_names, AUTH_PSK);
        return SUCCESS;
 }
 
@@ -147,28 +153,27 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
 static status_t build(private_psk_authenticator_t *this, chunk_t ike_sa_init,
                                          chunk_t other_nonce, auth_payload_t **auth_payload)
 {
-       chunk_t shared_key;
+       shared_key_t *shared_key;
        chunk_t auth_data;
-       status_t status;
        identification_t *my_id, *other_id;
        
        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);
-       status = charon->credentials->get_shared_key(charon->credentials, my_id,
-                                                                                                other_id, &shared_key);
-       if (status != SUCCESS)
+       shared_key = charon->credentials->get_shared(charon->credentials, SHARED_IKE,
+                                                                                                my_id, other_id);
+       if (shared_key == NULL)
        {
                DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
-               return status;
+               return NOT_FOUND;
        }
-                       
-       auth_data = build_shared_key_signature(ike_sa_init, other_nonce, shared_key,
-                                                       my_id, this->ike_sa->get_skp_build(this->ike_sa),
-                                                       this->ike_sa->get_prf(this->ike_sa));
+       auth_data = build_shared_key_signature(ike_sa_init, other_nonce,
+                                                                       shared_key->get_key(shared_key), my_id,
+                                                                       this->ike_sa->get_skp_build(this->ike_sa),
+                                                                       this->ike_sa->get_prf(this->ike_sa));
+       shared_key->destroy(shared_key);
        DBG2(DBG_IKE, "successfully created shared key MAC");
-       chunk_free_randomized(&shared_key);
        *auth_payload = auth_payload_create();
        (*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
        (*auth_payload)->set_data(*auth_payload, auth_data);
index c1c5bcaac00bed6312fa3d10b98173b3fe0592c1..366678f5d4afa6171f72c1c239bf7139077b6800 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file psk_authenticator.h
- *
- * @brief Interface of psk_authenticator_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 psk_authenticator psk_authenticator
+ * @{ @ingroup authenticators
  */
 
 #ifndef PSK_AUTHENTICATOR_H_
@@ -28,13 +28,7 @@ typedef struct psk_authenticator_t psk_authenticator_t;
 #include <sa/authenticators/authenticator.h>
 
 /**
- * @brief Implementation of the authenticator_t interface using AUTH_PSK.
- *
- * @b Constructors:
- *  - psk_authenticator_create()
- *  - authenticator_create() using auth_method AUTH_PSK
- *
- * @ingroup authenticators
+ * Implementation of the authenticator_t interface using AUTH_PSK.
  */
 struct psk_authenticator_t {
 
@@ -45,13 +39,11 @@ struct psk_authenticator_t {
 };
 
 /**
- * @brief Creates an authenticator for AUTH_PSK.
+ * Creates an authenticator for AUTH_PSK.
  *
  * @param ike_sa               associated ike_sa
  * @return                             psk_authenticator_t object
- *
- * @ingroup authenticators
  */
 psk_authenticator_t *psk_authenticator_create(ike_sa_t *ike_sa);
 
-#endif /* PSK_AUTHENTICATOR_H_ */
+#endif /* PSK_AUTHENTICATOR_H_ @} */
index ba0fad1e36f8c1fb49c791a665bb99ed94f631a1..becef184177f9c1b9035a8cf6db9572e87f6d4f7 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file rsa_authenticator.c
- *
- * @brief Implementation of rsa_authenticator_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
@@ -26,6 +21,7 @@
 #include "rsa_authenticator.h"
 
 #include <daemon.h>
+#include <credentials/auth_info.h>
 
 
 typedef struct private_rsa_authenticator_t private_rsa_authenticator_t;
@@ -58,11 +54,12 @@ extern chunk_t build_tbs_octets(chunk_t ike_sa_init, chunk_t nonce,
 static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
                                           chunk_t my_nonce, auth_payload_t *auth_payload)
 {
-       status_t status;
+       public_key_t *public;
        chunk_t auth_data, octets;
        identification_t *other_id;
-       ca_info_t *issuer;
        prf_t *prf;
+       auth_info_t *auth;
+       status_t status = FAILED;
        
        other_id = this->ike_sa->get_other_id(this->ike_sa);
        
@@ -74,16 +71,27 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
        prf = this->ike_sa->get_prf(this->ike_sa);
        prf->set_key(prf, this->ike_sa->get_skp_verify(this->ike_sa));
        octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, prf);
-       status = charon->credentials->verify_signature(charon->credentials,
-                                                                 octets, auth_data, other_id, &issuer);
-       chunk_free(&octets);
        
-       if (status == SUCCESS)
+       auth = this->ike_sa->get_other_auth(this->ike_sa);
+       public = charon->credentials->get_public(charon->credentials, KEY_RSA,
+                                                                                        other_id, auth);
+       if (public)
        {
-               this->ike_sa->set_other_ca(this->ike_sa, issuer);
-               DBG1(DBG_IKE, "authentication of '%D' with %N successful",
-                                          other_id, auth_method_names, AUTH_RSA);
+               /* We are currently fixed to SHA1 hashes.
+                * TODO: allow other hash algorithms and note it in "auth" */
+               if (public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, octets, auth_data))
+               {
+                       DBG1(DBG_IKE, "authentication of %D with %N successful",
+                                                  other_id, auth_method_names, AUTH_RSA);
+                       status = SUCCESS;
+               }
+               public->destroy(public);
        }
+       else
+       {
+               DBG1(DBG_IKE, "no trusted public key found for %D", other_id);
+       }
+       chunk_free(&octets);
        return status;
 }
 
@@ -94,43 +102,47 @@ static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
                                          chunk_t other_nonce, auth_payload_t **auth_payload)
 {
        chunk_t octets, auth_data;
-       status_t status;
-       rsa_public_key_t *my_pubkey;
+       status_t status = FAILED;
+       private_key_t *private;
        identification_t *my_id;
        prf_t *prf;
+       auth_info_t *auth;
 
        my_id = this->ike_sa->get_my_id(this->ike_sa);
-       DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
+       DBG1(DBG_IKE, "authentication of %D (myself) with %N",
                 my_id, auth_method_names, AUTH_RSA);
-       DBG2(DBG_IKE, "looking for RSA public key belonging to '%D'...", my_id);
-
-       my_pubkey = charon->credentials->get_rsa_public_key(charon->credentials, my_id);
-       if (my_pubkey == NULL)
+       
+       auth = this->ike_sa->get_my_auth(this->ike_sa);
+       private = charon->credentials->get_private(charon->credentials, KEY_RSA,
+                                                                                          my_id, auth);
+       if (private == NULL)
        {
-               DBG1(DBG_IKE, "no RSA public key found for '%D'", my_id);
+               DBG1(DBG_IKE, "no RSA private key found for %D", my_id);
                return NOT_FOUND;
        }
-       DBG2(DBG_IKE, "  matching RSA public key found");
-
        prf = this->ike_sa->get_prf(this->ike_sa);
        prf->set_key(prf, this->ike_sa->get_skp_build(this->ike_sa));
        octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, prf);
-       status = charon->credentials->rsa_signature(charon->credentials,
-                                                                               my_pubkey, HASH_SHA1, octets, &auth_data);
-       chunk_free(&octets);
-
-       if (status != SUCCESS)
+       /* we currently use always SHA1 for signatures, 
+        * TODO: support other hashes depending on configuration/auth */
+       if (private->sign(private, SIGN_RSA_EMSA_PKCS1_SHA1, octets, &auth_data))
        {
-               DBG1(DBG_IKE, "building RSA signature with SHA-1 hash failed");
-               return status;
+               auth_payload_t *payload = auth_payload_create();
+               payload->set_auth_method(payload, AUTH_RSA);
+               payload->set_data(payload, auth_data);
+               *auth_payload = payload;
+               chunk_free(&auth_data);
+               status = SUCCESS;
+               DBG2(DBG_IKE, "successfully signed with RSA private key");
        }
-       DBG2(DBG_IKE, "successfully signed with RSA private key");
+       else
+       {
+               DBG1(DBG_IKE, "building RSA signature failed");
+       }
+       chunk_free(&octets);
+       private->destroy(private);
        
-       *auth_payload = auth_payload_create();
-       (*auth_payload)->set_auth_method(*auth_payload, AUTH_RSA);
-       (*auth_payload)->set_data(*auth_payload, auth_data);
-       chunk_free(&auth_data);
-       return SUCCESS;
+       return status;
 }
 
 /**
index cc5cc0150b809f33dff689d797168a197969bf76..f5e41a917a867175e770fed0649d2aa7e61459e8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file rsa_authenticator.h
- *
- * @brief Interface of rsa_authenticator_t.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 rsa_authenticator rsa_authenticator
+ * @{ @ingroup authenticators
  */
 
 #ifndef RSA_AUTHENTICATOR_H_
@@ -28,13 +28,7 @@ typedef struct rsa_authenticator_t rsa_authenticator_t;
 #include <sa/authenticators/authenticator.h>
 
 /**
- * @brief Implementation of the authenticator_t interface using AUTH_RSA.
- *
- * @b Constructors:
- *  - rsa_authenticator_create()
- *  - authenticator_create() using auth_method AUTH_RSA
- *
- * @ingroup authenticators
+ * Implementation of the authenticator_t interface using AUTH_RSA.
  */
 struct rsa_authenticator_t {
 
@@ -45,13 +39,11 @@ struct rsa_authenticator_t {
 };
 
 /**
- * @brief Creates an authenticator for AUTH_RSA.
+ * Creates an authenticator for AUTH_RSA.
  *
  * @param ike_sa               associated ike_sa
  * @return                             rsa_authenticator_t object
- *
- * @ingroup authenticators
  */
 rsa_authenticator_t *rsa_authenticator_create(ike_sa_t *ike_sa);
 
-#endif /* RSA_AUTHENTICATOR_H_ */
+#endif /* RSA_AUTHENTICATOR_H_ @} */
index b6c71a8b5b3ab39c8e90998e243f7033d94cc6b3..225b8902d46b47b3ae16645756e05505290ef76f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_sa.c
- *
- * @brief Implementation of child_sa_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
@@ -20,6 +13,8 @@
  * WITHOUT ANY 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
index b801dd012d0a72c1e93cec069e727d396dd6b2f1..b8186ef51b66fa6b98f357e735eff7feee26b007 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_sa.h
- *
- * @brief Interface of child_sa_t.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Martin Willi
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
  * WITHOUT ANY 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 child_sa child_sa
+ * @{ @ingroup sa
+ */
 
 #ifndef CHILD_SA_H_
 #define CHILD_SA_H_
@@ -35,7 +34,7 @@ typedef struct child_sa_t child_sa_t;
 #include <config/child_cfg.h>
 
 /**
- * @brief States of a CHILD_SA
+ * States of a CHILD_SA
  */
 enum child_sa_state_t {
        
@@ -71,7 +70,7 @@ enum child_sa_state_t {
 extern enum_name_t *child_sa_state_names;
 
 /**
- * @brief Represents an IPsec SAs between two hosts.
+ * Represents an IPsec SAs between two hosts.
  * 
  * A child_sa_t contains two SAs. SAs for both
  * directions are managed in one child_sa_t object. Both
@@ -86,57 +85,47 @@ extern enum_name_t *child_sa_state_names;
  * - A calls child_sa_t.update to update the already allocated SPIs with the chosen proposal
  * 
  * Once SAs are set up, policies can be added using add_policies.
- * 
- * 
- * @b Constructors:
- *  - child_sa_create()
- * 
- * @ingroup sa
  */
 struct child_sa_t {
        
        /**
-        * @brief Get the name of the config this CHILD_SA uses.
+        * Get the name of the config this CHILD_SA uses.
         *
-        * @param this                  calling object
-        * @return                              name
+        * @return                      name
         */
        char* (*get_name) (child_sa_t *this);
        
        /**
-        * @brief Get the reqid of the CHILD SA.
+        * Get the reqid of the CHILD SA.
         * 
         * Every CHILD_SA has a reqid. The kernel uses this ID to
         * identify it.
         *
-        * @param this          calling object
         * @return                      reqid of the CHILD SA
         */
        u_int32_t (*get_reqid)(child_sa_t *this);
        
        /**
-        * @brief Get the SPI of this CHILD_SA.
+        * Get the SPI of this CHILD_SA.
         * 
         * Set the boolean parameter inbound to TRUE to
         * get the SPI for which we receive packets, use
         * FALSE to get those we use for sending packets.
         *
-        * @param this          calling object
         * @param inbound       TRUE to get inbound SPI, FALSE for outbound.
         * @return                      spi of the CHILD SA
         */
        u_int32_t (*get_spi) (child_sa_t *this, bool inbound);
        
        /**
-        * @brief Get the protocol which this CHILD_SA uses to protect traffic.
+        * Get the protocol which this CHILD_SA uses to protect traffic.
         *
-        * @param this          calling object
         * @return                      AH | ESP
         */
        protocol_id_t (*get_protocol) (child_sa_t *this);
        
        /**
-        * @brief Get info and statistics about this CHILD_SA.
+        * Get info and statistics about this CHILD_SA.
         *
         * @param mode          mode this IKE_SA uses
         * @param encr_algo     encryption algorithm used by this CHILD_SA.
@@ -155,7 +144,7 @@ struct child_sa_t {
                                          u_int32_t *use_fwd);
        
        /**
-        * @brief Allocate SPIs for given proposals.
+        * Allocate SPIs for given proposals.
         * 
         * Since the kernel manages SPIs for us, we need
         * to allocate them. If a proposal contains more
@@ -163,15 +152,13 @@ struct child_sa_t {
         * allocated. SPIs are stored internally and written
         * back to the proposal.
         *
-        * @param this          calling object
         * @param proposals     list of proposals for which SPIs are allocated
         */
        status_t (*alloc)(child_sa_t *this, linked_list_t* proposals);
        
        /**
-        * @brief Install the kernel SAs for a proposal, without previous SPI allocation.
+        * Install the kernel SAs for a proposal, without previous SPI allocation.
         *
-        * @param this          calling object
         * @param proposal      proposal for which SPIs are allocated
         * @param mode          mode for the CHILD_SA
         * @param prf_plus      key material to use for key derivation
@@ -181,11 +168,10 @@ struct child_sa_t {
                                        prf_plus_t *prf_plus);
        
        /**
-        * @brief Install the kernel SAs for a proposal, after SPIs have been allocated.
+        * Install the kernel SAs for a proposal, after SPIs have been allocated.
         *
         * Updates an SA, for which SPIs are already allocated via alloc().
         *
-        * @param this          calling object
         * @param proposal      proposal for which SPIs are allocated
         * @param mode          mode for the CHILD_SA
         * @param prf_plus      key material to use for key derivation
@@ -195,11 +181,10 @@ struct child_sa_t {
                                           prf_plus_t *prf_plus);
 
        /**
-        * @brief Update the hosts in the kernel SAs and policies.
+        * Update the hosts in the kernel SAs and policies.
         *
         * The CHILD must be INSTALLED to do this update.
         *
-        * @param this          calling object
         * @param me            the new local host
         * @param other         the new remote host
         * @param                       TRUE to use UDP encapsulation for NAT traversal
@@ -209,12 +194,11 @@ struct child_sa_t {
                                                         bool encap);
        
        /**
-        * @brief Install the policies using some traffic selectors.
+        * Install the policies using some traffic selectors.
         *
         * Supplied lists of traffic_selector_t's specify the policies
         * to use for this child sa.
         *
-        * @param this          calling object
         * @param my_ts         traffic selectors for local site
         * @param other_ts      traffic selectors for remote site
         * @param mode          mode for the SA: tunnel/transport
@@ -224,18 +208,16 @@ struct child_sa_t {
                                                         linked_list_t *other_ts_list, mode_t mode);
        
        /**
-        * @brief Get the traffic selectors of added policies of local host.
+        * Get the traffic selectors of added policies of local host.
         *
-        * @param this          calling object
         * @param local         TRUE for own traffic selectors, FALSE for remote
         * @return                      list of traffic selectors
         */     
        linked_list_t* (*get_traffic_selectors) (child_sa_t *this, bool local);
        
        /**
-        * @brief Get the time of this child_sa_t's last use (i.e. last use of any of its policies)
+        * Get the time of this child_sa_t's last use (i.e. last use of any of its policies)
         * 
-        * @param this          calling object
         * @param inbound       query for in- or outbound usage
         * @param use_time      the time
         * @return                      SUCCESS or FAILED
@@ -243,48 +225,42 @@ struct child_sa_t {
        status_t (*get_use_time) (child_sa_t *this, bool inbound, time_t *use_time);
        
        /**
-        * @brief Get the state of the CHILD_SA.
-        *
-        * @param this          calling object
+        * Get the state of the CHILD_SA.
         */     
        child_sa_state_t (*get_state) (child_sa_t *this);
        
        /**
-        * @brief Set the state of the CHILD_SA.
+        * Set the state of the CHILD_SA.
         *
-        * @param this          calling object
+        * @param state         state to set on CHILD_SA
         */     
        void (*set_state) (child_sa_t *this, child_sa_state_t state);
        
        /**
-        * @brief Get the config used to set up this child sa.
+        * Get the config used to set up this child sa.
         *
-        * @param this          calling object
         * @return                      child_cfg
         */
        child_cfg_t* (*get_config) (child_sa_t *this);
        
        /**
-        * @brief Set the virtual IP used received from IRAS.
+        * Set the virtual IP used received from IRAS.
         *
         * To allow proper setup of firewall rules, the virtual IP is required
         * for filtering.
         *
-        * @param this          calling object
         * @param ip            own virtual IP
         */
        void (*set_virtual_ip) (child_sa_t *this, host_t *ip);
        
        /**
-        * @brief Destroys a child_sa.
-        *
-        * @param this          calling object
+        * Destroys a child_sa.
         */
        void (*destroy) (child_sa_t *this);
 };
 
 /**
- * @brief Constructor to create a new child_sa_t.
+ * Constructor to create a new child_sa_t.
  *
  * @param me                   own address
  * @param other                        remote address
@@ -294,11 +270,9 @@ struct child_sa_t {
  * @param reqid                        reqid of old CHILD_SA when rekeying, 0 otherwise
  * @param encap                        TRUE to enable UDP encapsulation (NAT traversal)
  * @return                             child_sa_t object
- * 
- * @ingroup sa
  */
 child_sa_t * child_sa_create(host_t *me, host_t *other,
                                                         identification_t *my_id, identification_t* other_id,
                                                         child_cfg_t *config, u_int32_t reqid, bool encap);
 
-#endif /*CHILD_SA_H_*/
+#endif /*CHILD_SA_H_ @} */
index f40af4eed708beebd7505ac5159b10db22f68a5f..a913a0735c31e797cb95142703d823080acb269f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file connect_manager.c
- *
- * @brief Implementation of connect_manager_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "connect_manager.h"
@@ -1516,7 +1511,14 @@ connect_manager_t *connect_manager_create()
        this->public.set_responder_data = (status_t(*)(connect_manager_t*,chunk_t,chunk_t,linked_list_t*))set_responder_data;
        this->public.process_check = (void(*)(connect_manager_t*,message_t*))process_check;
        
-       this->hasher = hasher_create(HASH_SHA1);
+       this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+       if (hasher == NULL)
+       {
+               DBG1(DBG_IKE, "unable to create connect manager, SHA1 not supported");
+               free(this);
+               return NULL;
+       }
+       
        this->checklists = linked_list_create();
        this->initiated = linked_list_create();
        
index 2f3e9109bee4bd48be0d44f8ffe66e3352f65ce6..c1a44355782565b9fd34176c1ce3e3c0e9115853 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file connect_manager.h
- * 
- * @brief Interface of connect_manager_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 connect_manager connect_manager
+ * @{ @ingroup sa
  */
 
 #ifndef CONNECT_MANAGER_H_
@@ -31,21 +31,15 @@ typedef struct connect_manager_t connect_manager_t;
 #include <utils/identification.h>
 
 /**
- * @brief The connection manager is responsible for establishing a direct
+ * The connection manager is responsible for establishing a direct
  * connection with another peer.
- * 
- * @b Constructors:
- * - connect_manager_create()
- * 
- * @ingroup sa
  */
 struct connect_manager_t {
        
        /**
-        * @brief Checks if a there is already a mediated connection registered
+        * Checks if a there is already a mediated connection registered
         * between two peers.
         * 
-        * @param this                          the manager object
         * @param id                            my id
         * @param peer_id                       the other peer's id
         * @param mediated_sa           the IKE_SA ID of the mediated connection
@@ -59,10 +53,9 @@ struct connect_manager_t {
                        ike_sa_id_t *mediated_sa, child_cfg_t *child);
        
        /**
-        * @brief Checks if there are waiting connections with a specific peer.
+        * Checks if there are waiting connections with a specific peer.
         * If so, reinitiate them.
         * 
-        * @param this                          the manager object
         * @param id                            my id
         * @param peer_id                       the other peer's id
         */
@@ -70,9 +63,8 @@ struct connect_manager_t {
                        identification_t *id, identification_t *peer_id);
        
        /**
-        * @brief Creates a checklist and sets the initiator's data.
+        * Creates a checklist and sets the initiator's data.
         * 
-        * @param this                          the manager object
         * @param initiator                     ID of the initiator
         * @param responder                     ID of the responder
         * @param session_id            the session ID provided by the initiator
@@ -80,18 +72,16 @@ struct connect_manager_t {
         * @param endpoints                     the initiator's endpoints
         * @param is_initiator          TRUE, if the caller of this method is the initiator
         *                                                      FALSE, otherwise
-        * @returns
-        *                                                      SUCCESS
+        * @returns                                     SUCCESS
         */
        status_t (*set_initiator_data) (connect_manager_t *this,
                identification_t *initiator, identification_t *responder,
                chunk_t session_id, chunk_t key, linked_list_t *endpoints, bool is_initiator);
        
        /**
-        * @brief Updates a checklist and sets the responder's data. The checklist's
+        * Updates a checklist and sets the responder's data. The checklist's
         * state is advanced to WAITING which means that checks will be sent.
         * 
-        * @param this                          the manager object
         * @param session_id            the session ID
         * @param chunk_t                       the responder's key
         * @param endpoints                     the responder's endpoints 
@@ -104,28 +94,23 @@ struct connect_manager_t {
        
        
        /**
-        * @brief Processes a connectivity check
+        * Processes a connectivity check
         * 
-        * @param this                          the manager object
         * @param message                       the received message
         */
        void (*process_check) (connect_manager_t *this, message_t *message);
        
        /**
-        * @brief Destroys the manager with all data.
-        * 
-        * @param this                           the manager object
+        * Destroys the manager with all data.
         */
        void (*destroy) (connect_manager_t *this);
 };
 
 /**
- * @brief Create a manager.
+ * Create a manager.
  * 
  * @returns    connect_manager_t object
- * 
- * @ingroup sa
  */
 connect_manager_t *connect_manager_create(void);
 
-#endif /*CONNECT_MANAGER_H_*/
+#endif /*CONNECT_MANAGER_H_ @} */
index 93aa08965a7c2c3a5e9f2e1ab55b30128ddcf1b5..4e28b27dc46d8b92804e6b5ab1946d5d56341ae7 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa.c
- *
- * @brief Implementation of ike_sa_t.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
@@ -21,6 +14,8 @@
  * WITHOUT ANY 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/time.h>
@@ -53,7 +48,8 @@
 #include <sa/tasks/ike_auth.h>
 #include <sa/tasks/ike_auth_lifetime.h>
 #include <sa/tasks/ike_config.h>
-#include <sa/tasks/ike_cert.h>
+#include <sa/tasks/ike_cert_pre.h>
+#include <sa/tasks/ike_cert_post.h>
 #include <sa/tasks/ike_rekey.h>
 #include <sa/tasks/ike_reauth.h>
 #include <sa/tasks/ike_delete.h>
@@ -121,6 +117,16 @@ struct private_ike_sa_t {
         */
        peer_cfg_t *peer_cfg;
        
+       /**
+        * associated authentication/authorization info for local peer
+        */
+       auth_info_t *my_auth;
+       
+       /**
+        * associated authentication/authorization info for remote peer
+        */
+       auth_info_t *other_auth;
+       
        /**
         * Juggles tasks to process messages
         */
@@ -153,11 +159,6 @@ struct private_ike_sa_t {
         */
        identification_t *other_id;
        
-       /**
-        * CA that issued the certificate of other
-        */
-       ca_info_t *other_ca;
-       
        /**
         * set of extensions the peer supports
         */
@@ -425,6 +426,22 @@ static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg)
        }
 }
 
+/**
+ * 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.
+ */
+static auth_info_t* get_other_auth(private_ike_sa_t *this)
+{
+       return this->other_auth;
+}
+
 /**
  * Implementation of ike_sa_t.send_keepalive
  */
@@ -1020,10 +1037,12 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
                this->task_manager->queue_task(this->task_manager, task);
                task = (task_t*)ike_natd_create(&this->public, TRUE);
                this->task_manager->queue_task(this->task_manager, task);
-               task = (task_t*)ike_cert_create(&this->public, TRUE);
+               task = (task_t*)ike_cert_pre_create(&this->public, TRUE);
                this->task_manager->queue_task(this->task_manager, task);
                task = (task_t*)ike_auth_create(&this->public, TRUE);
                this->task_manager->queue_task(this->task_manager, task);
+               task = (task_t*)ike_cert_post_create(&this->public, TRUE);
+               this->task_manager->queue_task(this->task_manager, task);
                task = (task_t*)ike_config_create(&this->public, TRUE);
                this->task_manager->queue_task(this->task_manager, task);
                task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
@@ -1112,10 +1131,12 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
                this->task_manager->queue_task(this->task_manager, task);
                task = (task_t*)ike_natd_create(&this->public, TRUE);
                this->task_manager->queue_task(this->task_manager, task);
-               task = (task_t*)ike_cert_create(&this->public, TRUE);
+               task = (task_t*)ike_cert_pre_create(&this->public, TRUE);
                this->task_manager->queue_task(this->task_manager, task);
                task = (task_t*)ike_auth_create(&this->public, TRUE);
                this->task_manager->queue_task(this->task_manager, task);
+               task = (task_t*)ike_cert_post_create(&this->public, TRUE);
+               this->task_manager->queue_task(this->task_manager, task);
                task = (task_t*)ike_config_create(&this->public, TRUE);
                this->task_manager->queue_task(this->task_manager, task);
                task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
@@ -1502,12 +1523,14 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
                                new->task_manager->queue_task(new->task_manager, task);
                                task = (task_t*)ike_natd_create(&new->public, TRUE);
                                new->task_manager->queue_task(new->task_manager, task);
-                               task = (task_t*)ike_cert_create(&new->public, TRUE);
+                               task = (task_t*)ike_cert_pre_create(&new->public, TRUE);
                                new->task_manager->queue_task(new->task_manager, task);
                                task = (task_t*)ike_config_create(&new->public, TRUE);
                                new->task_manager->queue_task(new->task_manager, task);
                                task = (task_t*)ike_auth_create(&new->public, TRUE);
                                new->task_manager->queue_task(new->task_manager, task);
+                               task = (task_t*)ike_cert_post_create(&new->public, TRUE);
+                               new->task_manager->queue_task(new->task_manager, task);
                                
                                while (to_restart->remove_last(to_restart, (void**)&child_cfg) == SUCCESS)
                                {
@@ -1606,22 +1629,6 @@ static void set_other_id(private_ike_sa_t *this, identification_t *other)
        this->other_id = other;
 }
 
-/**
- * Implementation of ike_sa_t.get_other_ca.
- */
-static ca_info_t* get_other_ca(private_ike_sa_t *this)
-{
-       return this->other_ca;
-}
-
-/**
- * Implementation of ike_sa_t.set_other_ca.
- */
-static void set_other_ca(private_ike_sa_t *this, ca_info_t *other_ca)
-{
-       this->other_ca = other_ca;
-}
-
 /**
  * Implementation of ike_sa_t.derive_keys.
  */
@@ -1643,14 +1650,16 @@ static status_t derive_keys(private_ike_sa_t *this,
        /* Create SAs general purpose PRF first, we may use it here */
        if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo))
        {
-               DBG1(DBG_IKE, "key derivation failed: no PSEUDO_RANDOM_FUNCTION");;
+               DBG1(DBG_IKE, "no %N selected",
+                        transform_type_names, PSEUDO_RANDOM_FUNCTION);
                return FAILED;
        }
-       this->prf = prf_create(algo->algorithm);
+       this->prf = lib->crypto->create_prf(lib->crypto, algo->algorithm);
        if (this->prf == NULL)
        {
-               DBG1(DBG_IKE, "key derivation failed: PSEUDO_RANDOM_FUNCTION "
-                        "%N not supported!", pseudo_random_function_names, algo->algorithm);
+               DBG1(DBG_IKE, "%N %N not supported!",
+                        transform_type_names, PSEUDO_RANDOM_FUNCTION,
+                        pseudo_random_function_names, algo->algorithm);
                return FAILED;
        }
        
@@ -1694,7 +1703,7 @@ static status_t derive_keys(private_ike_sa_t *this,
        
        /* SK_d is used for generating CHILD_SA key mat => child_prf */
        proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo);
-       this->child_prf = prf_create(algo->algorithm);
+       this->child_prf = lib->crypto->create_prf(lib->crypto, algo->algorithm);
        key_size = this->child_prf->get_key_size(this->child_prf);
        prf_plus->allocate_bytes(prf_plus, key_size, &key);
        DBG4(DBG_IKE, "Sk_d secret %B", &key);
@@ -1704,15 +1713,18 @@ static status_t derive_keys(private_ike_sa_t *this,
        /* SK_ai/SK_ar used for integrity protection => signer_in/signer_out */
        if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &algo))
        {
-               DBG1(DBG_IKE, "key derivation failed: no INTEGRITY_ALGORITHM");
+               DBG1(DBG_IKE, "no %N selected",
+                        transform_type_names, INTEGRITY_ALGORITHM);
                return FAILED;
        }
-       signer_i = signer_create(algo->algorithm);
-       signer_r = signer_create(algo->algorithm);
+       signer_i = lib->crypto->create_signer(lib->crypto, algo->algorithm);
+       signer_r = lib->crypto->create_signer(lib->crypto, algo->algorithm);
        if (signer_i == NULL || signer_r == NULL)
        {
-               DBG1(DBG_IKE, "key derivation failed: INTEGRITY_ALGORITHM "
-                       "%N not supported!", integrity_algorithm_names ,algo->algorithm);
+               DBG1(DBG_IKE, "%N %N not supported!",
+                        transform_type_names, INTEGRITY_ALGORITHM,
+                        integrity_algorithm_names ,algo->algorithm);
+               prf_plus->destroy(prf_plus);
                return FAILED;
        }
        key_size = signer_i->get_key_size(signer_i);
@@ -1741,16 +1753,21 @@ static status_t derive_keys(private_ike_sa_t *this,
        /* SK_ei/SK_er used for encryption => crypter_in/crypter_out */
        if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &algo))
        {
-               DBG1(DBG_IKE, "key derivation failed: no ENCRYPTION_ALGORITHM");
+               DBG1(DBG_IKE, "no %N selected",
+                        transform_type_names, ENCRYPTION_ALGORITHM);
+               prf_plus->destroy(prf_plus);
                return FAILED;
        }
-       crypter_i = crypter_create(algo->algorithm, algo->key_size / 8);
-       crypter_r = crypter_create(algo->algorithm, algo->key_size / 8);
+       crypter_i = lib->crypto->create_crypter(lib->crypto, algo->algorithm,
+                                                                                       algo->key_size / 8);
+       crypter_r = lib->crypto->create_crypter(lib->crypto, algo->algorithm,
+                                                                                       algo->key_size / 8);
        if (crypter_i == NULL || crypter_r == NULL)
        {
-               DBG1(DBG_IKE, "key derivation failed: ENCRYPTION_ALGORITHM "
-                       "%N (key size %d) not supported!",
-                       encryption_algorithm_names, algo->algorithm, algo->key_size);
+               DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
+                        transform_type_names, ENCRYPTION_ALGORITHM,
+                        encryption_algorithm_names, algo->algorithm, algo->key_size);
+               prf_plus->destroy(prf_plus);
                return FAILED;
        }
        key_size = crypter_i->get_key_size(crypter_i);
@@ -2309,6 +2326,8 @@ 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);
        
        this->ike_sa_id->destroy(this->ike_sa_id);
        this->task_manager->destroy(this->task_manager);
@@ -2337,6 +2356,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        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_id = (ike_sa_id_t* (*)(ike_sa_t*)) get_id;
        this->public.get_my_host = (host_t* (*)(ike_sa_t*)) get_my_host;
        this->public.set_my_host = (void (*)(ike_sa_t*,host_t*)) set_my_host;
@@ -2347,8 +2368,6 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->public.set_my_id = (void (*)(ike_sa_t*,identification_t*)) set_my_id;
        this->public.get_other_id = (identification_t* (*)(ike_sa_t*)) get_other_id;
        this->public.set_other_id = (void (*)(ike_sa_t*,identification_t*)) set_other_id;
-       this->public.get_other_ca = (ca_info_t* (*)(ike_sa_t*)) get_other_ca;
-       this->public.set_other_ca = (void (*)(ike_sa_t*,ca_info_t*)) set_other_ca;
        this->public.enable_extension = (void(*)(ike_sa_t*, ike_extension_t extension))enable_extension;
        this->public.supports_extension = (bool(*)(ike_sa_t*, ike_extension_t extension))supports_extension;
        this->public.set_condition = (void (*)(ike_sa_t*, ike_condition_t,bool)) set_condition;
@@ -2401,7 +2420,6 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->other_host = host_create_any(AF_INET);
        this->my_id = identification_create_from_encoding(ID_ANY, chunk_empty);
        this->other_id = identification_create_from_encoding(ID_ANY, chunk_empty);
-       this->other_ca = NULL;
        this->extensions = 0;
        this->conditions = 0;
        this->crypter_in = NULL;
@@ -2420,6 +2438,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->time.delete = 0;
        this->ike_cfg = NULL;
        this->peer_cfg = NULL;
+       this->my_auth = auth_info_create();
+       this->other_auth = auth_info_create();
        this->task_manager = task_manager_create(&this->public);
        this->unique_id = ++unique_id;
        this->my_virtual_ip = NULL;
index 975447d9c9f671ebdd05adb62d4f6a18bc363dfb..f3d96f9deaa12a62fab5122240abd1b5e0172eaf 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa.h
- *
- * @brief Interface of ike_sa_t.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * WITHOUT ANY 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 ike_sa ike_sa
+ * @{ @ingroup sa
  */
 
 #ifndef IKE_SA_H_
@@ -42,40 +42,32 @@ typedef struct ike_sa_t ike_sa_t;
 #include <crypto/prfs/prf.h>
 #include <crypto/crypters/crypter.h>
 #include <crypto/signers/signer.h>
-#include <crypto/ca.h>
 #include <config/peer_cfg.h>
 #include <config/ike_cfg.h>
+#include <credentials/auth_info.h>
 
 /**
  * Timeout in milliseconds after that a half open IKE_SA gets deleted.
- *
- * @ingroup sa
  */
 #define HALF_OPEN_IKE_SA_TIMEOUT 30000
 
 /**
  * Interval to send keepalives when NATed, in seconds.
- *
- * @ingroup sa
  */
 #define KEEPALIVE_INTERVAL 20
 
 /**
  * After which time rekeying should be retried if it failed, in seconds.
- *
- * @ingroup sa
  */
 #define RETRY_INTERVAL 30
 
 /**
  * Jitter to subtract from RETRY_INTERVAL to randomize rekey retry.
- *
- * @ingroup sa
  */
 #define RETRY_JITTER 20
 
 /**
- * @brief Extensions (or optional features) the peer supports
+ * Extensions (or optional features) the peer supports
  */
 enum ike_extension_t {
        
@@ -91,7 +83,7 @@ enum ike_extension_t {
 };
 
 /**
- * @brief Conditions of an IKE_SA, change during its lifetime
+ * Conditions of an IKE_SA, change during its lifetime
  */
 enum ike_condition_t {
        
@@ -119,6 +111,11 @@ enum ike_condition_t {
         * peer has ben authenticated using EAP
         */
        COND_EAP_AUTHENTICATED = (1<<4),
+
+       /**
+        * received a certificate request from the peer
+        */
+       COND_CERTREQ_SEEN = (1<<4),
 };
 
 /**
@@ -138,7 +135,7 @@ enum statistic_t {
 };
 
 /**
- * @brief State of an IKE_SA.
+ * State of an IKE_SA.
  *
  * An IKE_SA passes various states in its lifetime. A newly created
  * SA is in the state CREATED.
@@ -173,8 +170,6 @@ enum statistic_t {
                          X
                         / \
    @endverbatim
- *
- * @ingroup sa
  */
 enum ike_sa_state_t {
        
@@ -210,365 +205,323 @@ enum ike_sa_state_t {
 extern enum_name_t *ike_sa_state_names;
 
 /**
- * @brief Class ike_sa_t representing an IKE_SA.
+ * Class ike_sa_t representing an IKE_SA.
  *
  * An IKE_SA contains crypto information related to a connection
  * with a peer. It contains multiple IPsec CHILD_SA, for which
  * it is responsible. All traffic is handled by an IKE_SA, using
  * the task manager and its tasks.
- *
- * @b Constructors:
- * - ike_sa_create()
- * 
- * @ingroup sa
  */
 struct ike_sa_t {
 
        /**
-        * @brief Get the id of the SA.
+        * Get the id of the SA.
         * 
         * Returned ike_sa_id_t object is not getting cloned!
         *
-        * @param this                  calling object
         * @return                              ike_sa's ike_sa_id_t
         */
        ike_sa_id_t* (*get_id) (ike_sa_t *this);
        
        /**
-        * @brief Get the numerical ID uniquely defining this IKE_SA.
+        * Get the numerical ID uniquely defining this IKE_SA.
         *
-        * @param this                  calling object
         * @return                              unique ID
         */
        u_int32_t (*get_unique_id) (ike_sa_t *this);
        
        /**
-        * @brief Get the state of the IKE_SA.
+        * Get the state of the IKE_SA.
         *
-        * @param this                  calling object
         * @return                              state of the IKE_SA
         */
        ike_sa_state_t (*get_state) (ike_sa_t *this);
        
        /**
-        * @brief Set the state of the IKE_SA.
+        * Set the state of the IKE_SA.
         *
-        * @param this                  calling object
         * @param state                 state to set for the IKE_SA
         */
        void (*set_state) (ike_sa_t *this, ike_sa_state_t ike_sa);
        
        /**
-        * @brief Get the name of the connection this IKE_SA uses.
+        * Get the name of the connection this IKE_SA uses.
         *
-        * @param this                  calling object
         * @return                              name
         */
        char* (*get_name) (ike_sa_t *this);
        
        /**
-        * @brief Get statistic values from the IKE_SA.
+        * Get statistic values from the IKE_SA.
         *
-        * @param this                  calling object
         * @param kind                  kind of requested value
         * @return                              value as integer
         */
        u_int32_t (*get_statistic)(ike_sa_t *this, statistic_t kind);
        
        /**
-        * @brief Get the own host address.
+        * Get the own host address.
         * 
-        * @param this                  calling object
         * @return                              host address
         */
        host_t* (*get_my_host) (ike_sa_t *this);
        
        /**
-        * @brief Set the own host address.
+        * Set the own host address.
         * 
-        * @param this                  calling object
         * @param me                    host address
         */
        void (*set_my_host) (ike_sa_t *this, host_t *me);
        
        /**
-        * @brief Get the other peers host address.
+        * Get the other peers host address.
         * 
-        * @param this                  calling object
         * @return                              host address
         */
        host_t* (*get_other_host) (ike_sa_t *this);
        
        /**
-        * @brief Set the others host address.
+        * Set the others host address.
         * 
-        * @param this                  calling object
         * @param other                 host address
         */
        void (*set_other_host) (ike_sa_t *this, host_t *other);
        
        /**
-        * @brief Update the IKE_SAs host.
+        * Update the IKE_SAs host.
         *
         * Hosts may be NULL to use current host.
         *
-        * @param this                  calling object
         * @param me                    new local host address, or NULL
         * @param other                 new remote host address, or NULL
         */
        void (*update_hosts)(ike_sa_t *this, host_t *me, host_t *other);
        
        /**
-        * @brief Get the own identification.
+        * Get the own identification.
         * 
-        * @param this                  calling object
         * @return                              identification
         */
        identification_t* (*get_my_id) (ike_sa_t *this);
        
        /**
-        * @brief Set the own identification.
+        * Set the own identification.
         * 
-        * @param this                  calling object
         * @param me                    identification
         */
        void (*set_my_id) (ike_sa_t *this, identification_t *me);
        
        /**
-        * @brief Get the other peer's identification.
+        * Get the other peer's identification.
         * 
-        * @param this                  calling object
         * @return                              identification
         */
        identification_t* (*get_other_id) (ike_sa_t *this);
        
        /**
-        * @brief Set the other peer's identification.
+        * Set the other peer's identification.
         * 
-        * @param this                  calling object
         * @param other                 identification
         */
        void (*set_other_id) (ike_sa_t *this, identification_t *other);
        
        /**
-        * @brief Get the other peer's certification authority
+        * Get the config used to setup this IKE_SA.
         * 
-        * @param this                  calling object
-        * @return                      ca_info_t record of other ca
-        */
-       ca_info_t* (*get_other_ca) (ike_sa_t *this);
-       
-       /**
-        * @brief Set the other peer's certification authority
-        * 
-        * @param this                  calling object
-        * @param other_ca              ca_info_t record of other ca
-        */
-       void (*set_other_ca) (ike_sa_t *this, ca_info_t *other_ca);
-       
-       /**
-        * @brief Get the config used to setup this IKE_SA.
-        * 
-        * @param this                  calling object
         * @return                              ike_config
         */
        ike_cfg_t* (*get_ike_cfg) (ike_sa_t *this);
        
        /**
-        * @brief Set the config to setup this IKE_SA.
+        * Set the config to setup this IKE_SA.
         * 
-        * @param this                  calling object
         * @param config                ike_config to use
         */
        void (*set_ike_cfg) (ike_sa_t *this, ike_cfg_t* config);
 
        /**
-        * @brief Get the peer config used by this IKE_SA.
+        * Get the peer config used by this IKE_SA.
         * 
-        * @param this                  calling object
         * @return                              peer_config
         */
        peer_cfg_t* (*get_peer_cfg) (ike_sa_t *this);
        
        /**
-        * @brief Set the peer config to use with this IKE_SA.
+        * Set the peer config to use with this IKE_SA.
         * 
-        * @param this                  calling object
         * @param config                peer_config to use
         */
        void (*set_peer_cfg) (ike_sa_t *this, peer_cfg_t *config);
        
        /**
-        * @brief Add an additional address for the peer.
+        * 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.
+        *
+        * @return                              auth_info for me
+        */
+       auth_info_t* (*get_other_auth)(ike_sa_t *this);
+       
+       /**
+        * Add an additional address for the peer.
         *
         * In MOBIKE, a peer may transmit additional addresses where it is
         * reachable. These are stored in the IKE_SA.
         * The own list of addresses is not stored, they are queried from
         * the kernel when required.
         *
-        * @param this                  calling object
         * @param host                  host to add to list
         */
        void (*add_additional_address)(ike_sa_t *this, host_t *host);
        
        /**
-        * @brief Create an iterator over all additional addresses of the peer.
+        * Create an iterator over all additional addresses of the peer.
         *
-        * @param this                  calling object
         * @return                              iterator over addresses
         */
        iterator_t* (*create_additional_address_iterator)(ike_sa_t *this);
        
        /**
-        * @brief Enable an extension the peer supports.
+        * Enable an extension the peer supports.
         *
         * If support for an IKE extension is detected, this method is called
         * to enable that extension and behave accordingly.
         *
-        * @param this                  calling object
         * @param extension             extension to enable
         */
        void (*enable_extension)(ike_sa_t *this, ike_extension_t extension);
        
        /**
-        * @brief Check if the peer supports an extension.
+        * Check if the peer supports an extension.
         *
-        * @param this                  calling object
         * @param extension             extension to check for support
         * @return                              TRUE if peer supports it, FALSE otherwise
         */
        bool (*supports_extension)(ike_sa_t *this, ike_extension_t extension);
        
        /**
-        * @brief Enable/disable a condition flag for this IKE_SA.
+        * Enable/disable a condition flag for this IKE_SA.
         *
-        * @param this                  calling object
         * @param condition             condition to enable/disable
         * @param enable                TRUE to enable condition, FALSE to disable
         */
        void (*set_condition) (ike_sa_t *this, ike_condition_t condition, bool enable);
 
        /**
-        * @brief Check if a condition flag is set.
+        * Check if a condition flag is set.
         *
-        * @param this                  calling object
         * @param condition             condition to check
         * @return                              TRUE if condition flag set, FALSE otherwise
         */
        bool (*has_condition) (ike_sa_t *this, ike_condition_t condition);
        
        /**
-        * @brief Get the number of queued MOBIKE address updates.
+        * Get the number of queued MOBIKE address updates.
         *
-        * @param this                  calling object
         * @return                              number of pending updates
         */
        u_int32_t (*get_pending_updates)(ike_sa_t *this);
        
        /**
-        * @brief Set the number of queued MOBIKE address updates.
+        * Set the number of queued MOBIKE address updates.
         *
-        * @param this                  calling object
         * @param updates               number of pending updates
         */
        void (*set_pending_updates)(ike_sa_t *this, u_int32_t updates);
 
 #ifdef P2P
        /**
-        * @brief Get the server reflexive host.
+        * Get the server reflexive host.
         * 
-        * @param this                  calling object
         * @return                              server reflexive host
         */
        host_t* (*get_server_reflexive_host) (ike_sa_t *this);
        
        /**
-        * @brief Set the server reflexive host.
+        * Set the server reflexive host.
         * 
-        * @param this                  calling object
         * @param host                  server reflexive host
         */
        void (*set_server_reflexive_host) (ike_sa_t *this, host_t *host);
        
        /**
-        * @brief Initiate the mediation of a mediated connection (i.e. initiate a
+        * Initiate the mediation of a mediated connection (i.e. initiate a
         * P2P_CONNECT exchange).
         * 
-        * @param this                          calling object
         * @param mediated_cfg          peer_cfg of the mediated connection
         * @return                              
-        *                                              - SUCCESS if initialization started
-        *                                              - DESTROY_ME if initialization failed
+        *                                                      - SUCCESS if initialization started
+        *                                                      - DESTROY_ME if initialization failed
         */
        status_t (*initiate_mediation) (ike_sa_t *this, peer_cfg_t *mediated_cfg);
        
        /**
-        * @brief Initiate the mediated connection
+        * Initiate the mediated connection
         * 
-        * @param this                          calling object
         * @param me                            local endpoint (gets cloned)
         * @param other                         remote endpoint (gets cloned)
         * @param childs                        linked list of child_cfg_t of CHILD_SAs (gets cloned)
         * @return                              
-        *                                              - SUCCESS if initialization started
-        *                                              - DESTROY_ME if initialization failed
+        *                                                      - SUCCESS if initialization started
+        *                                                      - DESTROY_ME if initialization failed
         */
        status_t (*initiate_mediated) (ike_sa_t *this, host_t *me, host_t *other,
                        linked_list_t *childs);
        
        /**
-        * @brief Relay data from one peer to another (i.e. initiate a
+        * Relay data from one peer to another (i.e. initiate a
         * P2P_CONNECT exchange).
         *
         * Data is cloned.
         * 
-        * @param this                          calling object
         * @param requester                     ID of the requesting peer
         * @param session_id            data of the P2P_SESSIONID payload
         * @param session_key           data of the P2P_SESSIONKEY payload
         * @param endpoints                     endpoints
         * @param response                      TRUE if this is a response
         * @return                              
-        *                                              - SUCCESS if relay started
-        *                                              - DESTROY_ME if relay failed
+        *                                                      - SUCCESS if relay started
+        *                                                      - DESTROY_ME if relay failed
         */
        status_t (*relay) (ike_sa_t *this, identification_t *requester, chunk_t session_id,
                        chunk_t session_key, linked_list_t *endpoints, bool response);
        
        /**
-        * @brief Send a callback to a peer.
+        * Send a callback to a peer.
         * 
         * Data is cloned.
         * 
-        * @param this                          calling object
         * @param peer_id                       ID of the other peer
         * @return
-        *                                              - SUCCESS if response started
-        *                                              - DESTROY_ME if response failed
+        *                                                      - SUCCESS if response started
+        *                                                      - DESTROY_ME if response failed
         */
        status_t (*callback) (ike_sa_t *this, identification_t *peer_id);
        
        /**
-        * @brief Respond to a P2P_CONNECT request.
+        * Respond to a P2P_CONNECT request.
         * 
         * Data is cloned.
         * 
-        * @param this                          calling object
         * @param peer_id                       ID of the other peer
         * @param session_id            the session ID supplied by the initiator
         * @return
-        *                                              - SUCCESS if response started
-        *                                              - DESTROY_ME if response failed
+        *                                                      - SUCCESS if response started
+        *                                                      - DESTROY_ME if response failed
         */
        status_t (*respond) (ike_sa_t *this, identification_t *peer_id, chunk_t session_id);
 #endif /* P2P */
        
        /**
-        * @brief Initiate a new connection.
+        * Initiate a new connection.
         *
         * The configs are owned by the IKE_SA after the call.
         * 
-        * @param this                  calling object
         * @param child_cfg             child config to create CHILD from
         * @return                              
         *                                              - SUCCESS if initialization started
@@ -577,12 +530,11 @@ struct ike_sa_t {
        status_t (*initiate) (ike_sa_t *this, child_cfg_t *child_cfg);
 
        /**
-        * @brief Route a policy in the kernel.
+        * 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 this                  calling object
         * @param child_cfg             child config to route
         * @return                              
         *                                              - SUCCESS if routed successfully
@@ -591,9 +543,8 @@ struct ike_sa_t {
        status_t (*route) (ike_sa_t *this, child_cfg_t *child_cfg);
 
        /**
-        * @brief Unroute a policy in the kernel previously routed.
+        * Unroute a policy in the kernel previously routed.
         *
-        * @param this                  calling object
         * @param reqid                 reqid of CHILD_SA to unroute
         * @return                              
         *                                              - SUCCESS if route removed
@@ -603,12 +554,11 @@ struct ike_sa_t {
        status_t (*unroute) (ike_sa_t *this, u_int32_t reqid);
        
        /**
-        * @brief Acquire connection setup for an installed kernel policy.
+        * 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 this                  calling object
         * @param reqid                 reqid of the CHILD_SA the policy belongs to.
         * @return                              
         *                                              - SUCCESS if initialization started
@@ -617,13 +567,12 @@ struct ike_sa_t {
        status_t (*acquire) (ike_sa_t *this, u_int32_t reqid);
        
        /**
-        * @brief Initiates the deletion of an IKE_SA.
+        * Initiates the deletion of an IKE_SA.
         * 
         * Sends a delete message to the remote peer and waits for
         * its response. If the response comes in, or a timeout occurs,
         * the IKE SA gets deleted.
         * 
-        * @param this                  calling object
         * @return
         *                                              - SUCCESS if deletion is initialized
         *                                              - INVALID_STATE, if the IKE_SA is not in 
@@ -633,7 +582,7 @@ struct ike_sa_t {
        status_t (*delete) (ike_sa_t *this);
        
        /**
-        * @brief Update IKE_SAs after network interfaces have changed.
+        * Update IKE_SAs after network interfaces have changed.
         *
         * Whenever the network interface configuration changes, the kernel
         * interface calls roam() on each IKE_SA. The IKE_SA then checks if
@@ -641,21 +590,19 @@ struct ike_sa_t {
         * If MOBIKE is supported, addresses are updated; If not, the tunnel is
         * restarted.
         *
-        * @param this                  calling object
         * @param address               TRUE if address list changed, FALSE otherwise
         * @return                              SUCCESS, FAILED, DESTROY_ME
         */
        status_t (*roam)(ike_sa_t *this, bool address);
        
        /**
-        * @brief Processes a incoming IKEv2-Message.
+        * Processes a incoming IKEv2-Message.
         *
         * Message processing may fail. If a critical failure occurs, 
         * process_message() return DESTROY_ME. Then the caller must 
         * destroy the IKE_SA immediatly, as it is unusable.
         * 
-        * @param this                  calling object
-        * @param message       message to process
+        * @param message               message to process
         * @return                              
         *                                              - SUCCESS
         *                                              - FAILED
@@ -664,12 +611,11 @@ struct ike_sa_t {
        status_t (*process_message) (ike_sa_t *this, message_t *message);
        
        /**
-        * @brief Generate a IKE message to send it to the peer.
+        * Generate a IKE message to send it to the peer.
         * 
         * This method generates all payloads in the message and encrypts/signs
         * the packet.
         * 
-        * @param this                  calling object
         * @param message               message to generate
         * @param packet                generated output packet
         * @return                              
@@ -681,9 +627,8 @@ struct ike_sa_t {
                                                                  packet_t **packet);
        
        /**
-        * @brief Retransmits a request.
+        * Retransmits a request.
         * 
-        * @param this                  calling object
         * @param message_id    ID of the request to retransmit
         * @return
         *                                              - SUCCESS
@@ -692,13 +637,12 @@ struct ike_sa_t {
        status_t (*retransmit) (ike_sa_t *this, u_int32_t message_id);
        
        /**
-        * @brief Sends a DPD request to the peer.
+        * Sends a DPD request to the peer.
         *
         * To check if a peer is still alive, periodic
         * empty INFORMATIONAL messages are sent if no
         * other traffic was received.
         * 
-        * @param this                  calling object
         * @return
         *                                              - SUCCESS
         *                                              - DESTROY_ME, if peer did not respond
@@ -706,19 +650,17 @@ struct ike_sa_t {
        status_t (*send_dpd) (ike_sa_t *this);
        
        /**
-        * @brief Sends a keep alive packet.
+        * Sends a keep alive packet.
         *
         * To refresh NAT tables in a NAT router
         * between the peers, periodic empty
         * UDP packets are sent if no other traffic
         * was sent.
-        *
-        * @param this                  calling object
         */
        void (*send_keepalive) (ike_sa_t *this);
 
        /**
-        * @brief Derive all keys and create the transforms for IKE communication.
+        * Derive all keys and create the transforms for IKE communication.
         *
         * Keys are derived using the diffie hellman secret, nonces and internal
         * stored SPIs.
@@ -726,7 +668,6 @@ struct ike_sa_t {
         * existing IKE_SA (rekeying). The SK_d key from the old IKE_SA
         * is included in the derivation process.
         *
-        * @param this                  calling object
         * @param proposal              proposal which contains algorithms to use
         * @param secret                secret derived from DH exchange, gets freed
         * @param nonce_i               initiators nonce
@@ -740,49 +681,43 @@ struct ike_sa_t {
                                                        bool initiator, prf_t *child_prf, prf_t *old_prf);
        
        /**
-        * @brief Get a multi purpose prf for the negotiated PRF function.
+        * Get a multi purpose prf for the negotiated PRF function.
         * 
-        * @param this                  calling object
         * @return                              pointer to prf_t object
         */
        prf_t *(*get_prf) (ike_sa_t *this);
        
        /**
-        * @brief Get the prf-object, which is used to derive keys for child SAs.
+        * Get the prf-object, which is used to derive keys for child SAs.
         * 
-        * @param this                  calling object
         * @return                              pointer to prf_t object
         */
        prf_t *(*get_child_prf) (ike_sa_t *this);
        
        /**
-        * @brief Get the key to build outgoing authentication data.
+        * Get the key to build outgoing authentication data.
         * 
-        * @param this                  calling object
         * @return                              pointer to prf_t object
         */
        chunk_t (*get_skp_build) (ike_sa_t *this);
        
        /**
-        * @brief Get the key to verify incoming authentication data.
+        * Get the key to verify incoming authentication data.
         * 
-        * @param this                  calling object
         * @return                              pointer to prf_t object
         */
        chunk_t (*get_skp_verify) (ike_sa_t *this);
        
        /**
-        * @brief Associates a child SA to this IKE SA
+        * Associates a child SA to this IKE SA
         * 
-        * @param this                  calling object
         * @param child_sa              child_sa to add
         */
        void (*add_child_sa) (ike_sa_t *this, child_sa_t *child_sa);
        
        /**
-        * @brief Get a CHILD_SA identified by protocol and SPI.
+        * Get a CHILD_SA identified by protocol and SPI.
         * 
-        * @param this                  calling object
         * @param protocol              protocol of the SA
         * @param spi                   SPI of the CHILD_SA
         * @param inbound               TRUE if SPI is inbound, FALSE if outbound
@@ -792,19 +727,17 @@ struct ike_sa_t {
                                                                 u_int32_t spi, bool inbound);
        
        /**
-        * @brief Create an iterator over all CHILD_SAs.
+        * Create an iterator over all CHILD_SAs.
         * 
-        * @param this                  calling object
         * @return                              iterator
         */
        iterator_t* (*create_child_sa_iterator) (ike_sa_t *this);
        
        /**
-        * @brief Rekey the CHILD SA with the specified reqid.
+        * Rekey the CHILD SA with the specified reqid.
         *
         * Looks for a CHILD SA owned by this IKE_SA, and start the rekeing.
         *
-        * @param this                  calling object
         * @param protocol              protocol of the SA
         * @param spi                   inbound SPI of the CHILD_SA
         * @return
@@ -814,13 +747,12 @@ struct ike_sa_t {
        status_t (*rekey_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
 
        /**
-        * @brief Close the CHILD SA with the specified protocol/SPI.
+        * Close the CHILD SA with the specified protocol/SPI.
         *
         * Looks for a CHILD SA owned by this IKE_SA, deletes it and
         * notify's the remote peer about the delete. The associated
         * states and policies in the kernel get deleted, if they exist.
         *
-        * @param this                  calling object
         * @param protocol              protocol of the SA
         * @param spi                   inbound SPI of the CHILD_SA
         * @return
@@ -830,11 +762,10 @@ struct ike_sa_t {
        status_t (*delete_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
 
        /**
-        * @brief Destroy a CHILD SA with the specified protocol/SPI.
+        * Destroy a CHILD SA with the specified protocol/SPI.
         *
         * Looks for a CHILD SA owned by this IKE_SA and destroys it.
         *
-        * @param this                  calling object
         * @param protocol              protocol of the SA
         * @param spi                   inbound SPI of the CHILD_SA
         * @return
@@ -844,99 +775,89 @@ struct ike_sa_t {
        status_t (*destroy_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
 
        /**
-        * @brief Rekey the IKE_SA.
+        * Rekey the IKE_SA.
         *
         * Sets up a new IKE_SA, moves all CHILDs to it and deletes this IKE_SA.
         *
-        * @param this                  calling object
         * @return                              - SUCCESS, if IKE_SA rekeying initiated
         */
        status_t (*rekey) (ike_sa_t *this);
 
        /**
-        * @brief Restablish the IKE_SA.
+        * Restablish the IKE_SA.
         *
         * Create a completely new IKE_SA with authentication, recreates all children
         * within the IKE_SA, closes this IKE_SA.
         *
-        * @param this                  calling object
         * @return                              DESTROY_ME to destroy the IKE_SA
         */
        status_t (*reestablish) (ike_sa_t *this);
        
        /**
-        * @brief Set the lifetime limit received from a AUTH_LIFETIME notify.
+        * Set the lifetime limit received from a AUTH_LIFETIME notify.
         *
-        * @param this                  calling object
         * @param lifetime              lifetime in seconds
         */
        void (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime);
        
        /**
-        * @brief Set the virtual IP to use for this IKE_SA and its children.
+        * Set the virtual IP to use for this IKE_SA and its children.
         *
         * The virtual IP is assigned per IKE_SA, not per CHILD_SA. It has the same
         * lifetime as the IKE_SA.
         *
-        * @param this                  calling object
+        * @param local                 TRUE to set local address, FALSE for remote
+        * @param ip                    IP to set as virtual IP
         */
        void (*set_virtual_ip) (ike_sa_t *this, bool local, host_t *ip);
        
        /**
-        * @brief Get the virtual IP configured.
+        * Get the virtual IP configured.
         *
-        * @param this                  calling object
         * @param local                 TRUE to get local virtual IP, FALSE for remote
+        * @return                              host_t *virtual IP
         */
        host_t* (*get_virtual_ip) (ike_sa_t *this, bool local);
        
        /**
-        * @brief Add a DNS server to the system.
+        * Add a DNS server to the system.
         *
         * 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.
         *
-        * @param this                  calling object
         * @param dns                   DNS server to install on the system
         */
        void (*add_dns_server) (ike_sa_t *this, host_t *dns);
        
        /**
-        * @brief Inherit all attributes of other to this after rekeying.
+        * Inherit all attributes of other to this after rekeying.
         *
         * When rekeying is completed, all CHILD_SAs, the virtual IP and all
         * outstanding tasks are moved from other to this.
         * As this call may initiate inherited tasks, a status is returned.
         *
-        * @param this                  calling object
         * @param other                 other task to inherit from
         * @return                              DESTROY_ME if initiation of inherited task failed
         */
        status_t (*inherit) (ike_sa_t *this, ike_sa_t *other);
                
        /**
-        * @brief Reset the IKE_SA, useable when initiating fails
-        *
-        * @param this                  calling object
+        * Reset the IKE_SA, useable when initiating fails
         */
        void (*reset) (ike_sa_t *this);
        
        /**
-        * @brief Destroys a ike_sa_t object.
-        *
-        * @param this                  calling object
+        * Destroys a ike_sa_t object.
         */
        void (*destroy) (ike_sa_t *this);
 };
 
 /**
- * @brief Creates an ike_sa_t object with a specific ID.
+ * Creates an ike_sa_t object with a specific ID.
  *
  * @param ike_sa_id    ike_sa_id_t object to associate with new IKE_SA
  * @return                             ike_sa_t object
- * 
- * @ingroup sa
  */
 ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id);
 
-#endif /* IKE_SA_H_ */
+#endif /* IKE_SA_H_ @} */
index a838c0b8a0afc70e7dce5c9ca99baa93390d2186..74105104046623c145ad7beb3206d8e4af62ff48 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa_id.c
- *
- * @brief Implementation of ike_sa_id_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 "ike_sa_id.h"
 
 #include <stdio.h>
index 0606b72229f7dcd93e1322a8ce7beb1eb0e4ec78..3d79235390a798e6610454938ee3837969cbc1fd 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa_id.h
- *
- * @brief Interface of ike_sa_id_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 ike_sa_id ike_sa_id
+ * @{ @ingroup sa
+ */
 
 #ifndef IKE_SA_ID_H_
 #define IKE_SA_ID_H_
@@ -29,119 +28,101 @@ typedef struct ike_sa_id_t ike_sa_id_t;
 
 #include <library.h>
 
-
 /**
- * @brief An object of type ike_sa_id_t is used to identify an IKE_SA.
+ * An object of type ike_sa_id_t is used to identify an IKE_SA.
  *
  * An IKE_SA is identified by its initiator and responder spi's.
  * Additionaly it contains the role of the actual running IKEv2-Daemon
  * for the specific IKE_SA (original initiator or responder).
- * 
- * @b Constructors:
- *  - ike_sa_id_create()
- * 
- * @ingroup sa
  */
 struct ike_sa_id_t {
 
        /**
-        * @brief Set the SPI of the responder.
+        * Set the SPI of the responder.
         *
         * This function is called when a request or reply of a IKE_SA_INIT is received.
         *
-        * @param this                          calling object
         * @param responder_spi         SPI of responder to set
         */
        void (*set_responder_spi) (ike_sa_id_t *this, u_int64_t responder_spi);
 
        /**
-        * @brief Set the SPI of the initiator.
+        * Set the SPI of the initiator.
         *
-        * @param this                          calling object
         * @param initiator_spi         SPI to set
         */
        void (*set_initiator_spi) (ike_sa_id_t *this, u_int64_t initiator_spi);
 
        /**
-        * @brief Get the initiator SPI.
+        * Get the initiator SPI.
         *
-        * @param this                          calling object
         * @return                                      SPI of the initiator
         */
        u_int64_t (*get_initiator_spi) (ike_sa_id_t *this);
 
        /**
-        * @brief Get the responder SPI.
+        * Get the responder SPI.
         *
-        * @param this                          calling object
         * @return                                      SPI of the responder
         */
        u_int64_t (*get_responder_spi) (ike_sa_id_t *this);
 
        /**
-        * @brief Check if two ike_sa_id_t objects are equal.
+        * Check if two ike_sa_id_t objects are equal.
         * 
         * Two ike_sa_id_t objects are equal if both SPI values and the role matches.
         *
-        * @param this                          calling object
         * @param other                         ike_sa_id_t object to check if equal
         * @return                                      TRUE if given ike_sa_id_t are equal, FALSE otherwise
         */
        bool (*equals) (ike_sa_id_t *this, ike_sa_id_t *other);
 
        /**
-        * @brief Replace all values of a given ike_sa_id_t object with values.
+        * Replace all values of a given ike_sa_id_t object with values.
         * from another ike_sa_id_t object.
         * 
         * After calling this function, both objects are equal.
         *
-        * @param this                          calling object
         * @param other                         ike_sa_id_t object from which values will be taken
         */
        void (*replace_values) (ike_sa_id_t *this, ike_sa_id_t *other);
 
        /**
-        * @brief Get the initiator flag.
+        * Get the initiator flag.
         *
-        * @param this                          calling object
         * @return                                      TRUE if we are the original initator
         */
        bool (*is_initiator) (ike_sa_id_t *this);
 
        /**
-        * @brief Switche the original initiator flag.
+        * Switche the original initiator flag.
         * 
-        * @param this                          calling object
         * @return                                      TRUE if we are the original initator after switch, FALSE otherwise
         */
        bool (*switch_initiator) (ike_sa_id_t *this);
 
        /**
-        * @brief Clones a given ike_sa_id_t object.
+        * Clones a given ike_sa_id_t object.
         *
-        * @param this                          calling object
         * @return                                      cloned ike_sa_id_t object
         */
        ike_sa_id_t *(*clone) (ike_sa_id_t *this);
 
        /**
-        * @brief Destroys an ike_sa_id_t object.
-        *
-        * @param this                          calling object
+        * Destroys an ike_sa_id_t object.
         */
        void (*destroy) (ike_sa_id_t *this);
 };
 
 /**
- * @brief Creates an ike_sa_id_t object with specific SPI's and defined role.
+ * Creates an ike_sa_id_t object with specific SPI's and defined role.
  *
  * @param initiator_spi                        initiators SPI
  * @param responder_spi                        responders SPI
  * @param is_initiaor                  TRUE if we are the original initiator
  * @return                                             ike_sa_id_t object
- * 
- * @ingroup sa
  */
-ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiaor);
+ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi,
+                                                          bool is_initiaor);
 
-#endif /*IKE_SA_ID_H_*/
+#endif /*IKE_SA_ID_H_ @} */
index 5e7f78af045e26d9770f1d15391a5a1efb3cc0f8..f004f0701445664f6c40221ce7acb18d490376ae 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa_manager.c
- *
- * @brief Implementation of ike_sa_mananger_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 <pthread.h>
@@ -30,6 +25,7 @@
 #include <sa/ike_sa_id.h>
 #include <bus/bus.h>
 #include <utils/linked_list.h>
+#include <crypto/hashers/hasher.h>
 
 typedef struct entry_t entry_t;
 
@@ -508,7 +504,6 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
        {
                identification_t *found_my_id, *found_other_id;
                host_t *found_my_host, *found_other_host;
-               int wc;
                
                if (!wait_for_entry(this, entry))
                {
@@ -541,8 +536,8 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
                         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, &wc) &&
-                       found_other_id->matches(found_other_id, other_id, &wc) &&
+                       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)))
                {
@@ -920,10 +915,15 @@ ike_sa_manager_t *ike_sa_manager_create()
        this->public.get_half_open_count = (int(*)(ike_sa_manager_t*,host_t*))get_half_open_count;
        
        /* initialize private variables */
+       this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED);
+       if (this->hasher == NULL)
+       {
+               DBG1(DBG_MGR, "manager initialization failed, no hasher supported");
+               free(this);
+               return NULL;
+       }
        this->ike_sa_list = linked_list_create();
        pthread_mutex_init(&this->mutex, NULL);
        this->randomizer = randomizer_create();
-       this->hasher = hasher_create(HASH_SHA1);
-       
        return &this->public;
 }
index a73a106ba3f8daaa05700aacf3897ce1ee32d4f8..cb25940c568b0e54888fff0c0ad9a9d49798e179 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_sa_manager.h
- * 
- * @brief Interface of ike_sa_manager_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 ike_sa_manager ike_sa_manager
+ * @{ @ingroup sa
  */
 
 #ifndef IKE_SA_MANAGER_H_
@@ -32,7 +32,7 @@ typedef struct ike_sa_manager_t ike_sa_manager_t;
 #include <config/peer_cfg.h>
 
 /**
- * @brief The IKE_SA-Manager is responsible for managing all initiated and responded IKE_SA's.
+ * The IKE_SA-Manager is responsible for managing all initiated and responded IKE_SA's.
  *
  * To avoid access from multiple threads, IKE_SAs must be checked out from
  * the manager, and checked in after usage. 
@@ -42,18 +42,12 @@ typedef struct ike_sa_manager_t ike_sa_manager_t;
  * This could be done by comparing thread-ids via pthread_self()...
  * 
  * @todo Managing of ike_sa_t objects in a hash table instead of linked list.
- * 
- * @b Constructors:
- * - ike_sa_manager_create()
- * 
- * @ingroup sa
  */
 struct ike_sa_manager_t {
        
        /**
-        * @brief Checkout an existing IKE_SA.
+        * Checkout an existing IKE_SA.
         * 
-        * @param this                          the manager object
         * @param ike_sa_id                     the SA identifier, will be updated
         * @returns                                     
         *                                                      - checked out IKE_SA if found
@@ -62,16 +56,15 @@ struct ike_sa_manager_t {
        ike_sa_t* (*checkout) (ike_sa_manager_t* this, ike_sa_id_t *sa_id);
        
        /**
-        * @brief Create and check out a new IKE_SA.
+        * Create and check out a new IKE_SA.
         * 
-        * @param this                          the manager object
         * @param initiator                     TRUE for initiator, FALSE otherwise
         * @returns                             created andchecked out IKE_SA
         */
        ike_sa_t* (*checkout_new) (ike_sa_manager_t* this, bool initiator);
        
        /**
-        * @brief Checkout an IKE_SA by a message.
+        * Checkout an IKE_SA by a message.
         * 
         * In some situations, it is necessary that the manager knows the
         * message to use for the checkout. This has the folloing reasons:
@@ -86,7 +79,6 @@ struct ike_sa_manager_t {
         * If processing the message does not make sense (for the reasons above),
         * NULL is returned.
         * 
-        * @param this                          the manager object
         * @param ike_sa_id                     the SA identifier, will be updated
         * @returns                                     
         *                                                      - checked out/created IKE_SA
@@ -95,7 +87,7 @@ struct ike_sa_manager_t {
        ike_sa_t* (*checkout_by_message) (ike_sa_manager_t* this, message_t *message);
        
        /**
-        * @brief Checkout an IKE_SA for initiation by a peer_config.
+        * Checkout an IKE_SA for initiation by a peer_config.
         *
         * To initiate, a CHILD_SA may be established within an existing IKE_SA.
         * This call checks for an existing IKE_SA by comparing the configuration.
@@ -104,7 +96,6 @@ struct ike_sa_manager_t {
         * If no IKE_SA is found, a new one is created. This is also the case when
         * the found IKE_SA is in the DELETING state.
         *
-        * @param this                          the manager object
         * @param peer_cfg                      configuration used to find an existing IKE_SA
         * @return                                      checked out/created IKE_SA
         */
@@ -112,14 +103,13 @@ struct ike_sa_manager_t {
                                                                         peer_cfg_t *peer_cfg);
        
        /**
-        * @brief Check out an IKE_SA a unique ID.
+        * Check out an IKE_SA a unique ID.
         *
         * Every IKE_SA and every CHILD_SA is uniquely identified by an ID. 
         * These checkout function uses, depending
         * on the child parameter, the unique ID of the IKE_SA or the reqid
         * of one of a IKE_SAs CHILD_SA.
         *
-        * @param this                          the manager object
         * @param id                            unique ID of the object
         * @param child                         TRUE to use CHILD, FALSE to use IKE_SA
         * @return
@@ -130,12 +120,11 @@ struct ike_sa_manager_t {
                                                                 bool child);
        
        /**
-        * @brief Check out an IKE_SA by the policy/connection name.
+        * Check out an IKE_SA by the policy/connection name.
         *
         * Check out the IKE_SA by the connections name or by a CHILD_SAs policy
         * name.
         *
-        * @param this                          the manager object
         * @param name                          name of the connection/policy
         * @param child                         TRUE to use policy name, FALSE to use conn name
         * @return
@@ -146,24 +135,22 @@ struct ike_sa_manager_t {
                                                                   bool child);
        
        /**
-        * @brief Create an iterator over all stored IKE_SAs.
+        * Create an iterator over all stored IKE_SAs.
         *
         * The avoid synchronization issues, the iterator locks access
         * to the manager exclusively, until it gets destroyed.
         * This iterator is for reading only! Writing will corrupt the manager.
         *
-        * @param this                          the manager object
         * @return                                      iterator over all IKE_SAs.
         */
        iterator_t *(*create_iterator) (ike_sa_manager_t* this);
        
        /**
-        * @brief Checkin the SA after usage.
+        * Checkin the SA after usage.
         * 
         * @warning the SA pointer MUST NOT be used after checkin! 
         * The SA must be checked out again!
         *  
-        * @param this                          the manager object
         * @param ike_sa_id                     the SA identifier, will be updated
         * @param ike_sa                        checked out SA
         * @returns                             
@@ -173,7 +160,7 @@ struct ike_sa_manager_t {
        status_t (*checkin) (ike_sa_manager_t* this, ike_sa_t *ike_sa);
        
        /**
-        * @brief Destroy a checked out SA.
+        * Destroy a checked out SA.
         *
         * The IKE SA is destroyed without notification of the remote peer.
         * Use this only if the other peer doesn't respond or behaves not
@@ -182,7 +169,6 @@ struct ike_sa_manager_t {
         * so this can be called if the SA is in a "unclean" state, without the
         * risk that another thread can get the SA.
         *
-        * @param this                          the manager object
         * @param ike_sa                        SA to delete
         * @returns                             
         *                                                      - SUCCESS if found
@@ -191,7 +177,7 @@ struct ike_sa_manager_t {
        status_t (*checkin_and_destroy) (ike_sa_manager_t* this, ike_sa_t *ike_sa);
        
        /**
-        * @brief Get the number of IKE_SAs which are in the connecting state.
+        * Get the number of IKE_SAs which are in the connecting state.
         *
         * To prevent the server from resource exhaustion, cookies and other
         * mechanisms are used. The number of half open IKE_SAs is a good
@@ -200,29 +186,24 @@ struct ike_sa_manager_t {
         * from this IP are counted.
         * Only SAs for which we are the responder are counted.
         * 
-        * @param this                          the manager object
         * @param ip                            NULL for all, IP for half open IKE_SAs with IP
         * @return                                      number of half open IKE_SAs
         */
        int (*get_half_open_count) (ike_sa_manager_t *this, host_t *ip);
        
        /**
-        * @brief Destroys the manager with all associated SAs.
+        * Destroys the manager with all associated SAs.
         * 
         * Threads will be driven out, so all SAs can be deleted cleanly.
-        * 
-        * @param this                           the manager object
         */
        void (*destroy) (ike_sa_manager_t *this);
 };
 
 /**
- * @brief Create a manager.
- * 
- * @returns    ike_sa_manager_t object
+ * Create a manager.
  * 
- * @ingroup sa
+ * @returns    ike_sa_manager_t object, NULL if initialization fails
  */
 ike_sa_manager_t *ike_sa_manager_create(void);
 
-#endif /*IKE_SA_MANAGER_H_*/
+#endif /*IKE_SA_MANAGER_H_ @} */
index f6137304d6ab5bc2d65e1631ba26b70b6527bd45..eac62a878a2313125035e61aebddd53423283ba7 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file mediation_manager.c
- *
- * @brief Implementation of mediation_manager_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "mediation_manager.h"
index 74acc4d4111f8922f02148f78baec92de57447aa..7b60741706cb5a47c15f26ec3694b2d5d4583bc6 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file mediation_manager.h
- * 
- * @brief Interface of mediation_manager_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 mediation_manager mediation_manager
+ * @{ @ingroup sa
  */
 
 #ifndef MEDIATION_MANAGER_H_
@@ -29,29 +29,22 @@ typedef struct mediation_manager_t mediation_manager_t;
 #include <utils/identification.h>
 
 /**
- * @brief The mediation manager is responsible for managing currently online
+ * The mediation manager is responsible for managing currently online
  * peers and registered requests for offline peers on the mediation server.
- * 
- * @b Constructors:
- * - mediation_manager_create()
- * 
- * @ingroup sa
  */
 struct mediation_manager_t {
        
        /**
-        * @brief Remove the IKE_SA of a peer.
+        * Remove the IKE_SA of a peer.
         * 
-        * @param this                          the manager object
         * @param ike_sa_id                     the IKE_SA ID of the peer's SA
         */
        void (*remove) (mediation_manager_t* this, ike_sa_id_t *ike_sa_id);
        
        /**
-        * @brief Update the ike_sa_id that is assigned to a peer's ID. If the peer
+        * Update the ike_sa_id that is assigned to a peer's ID. If the peer
         * is new, it gets a new record assigned. 
         * 
-        * @param this                          the manager object
         * @param peer_id                       the peer's ID
         * @param ike_sa_id                     the IKE_SA ID of the peer's SA
         */
@@ -59,9 +52,8 @@ struct mediation_manager_t {
                        ike_sa_id_t *ike_sa_id);
        
        /**
-        * @brief Checks if a specific peer is online.
+        * Checks if a specific peer is online.
         * 
-        * @param this                          the manager object
         * @param peer_id                       the peer's ID
         * @returns                                     
         *                                                      - IKE_SA ID of the peer's SA.
@@ -71,10 +63,9 @@ struct mediation_manager_t {
                        identification_t *peer_id);
        
        /**
-        * @brief Checks if a specific peer is online and registers the requesting
+        * Checks if a specific peer is online and registers the requesting
         * peer if it is not.
         * 
-        * @param this                          the manager object
         * @param peer_id                       the peer's ID
         * @param requester                     the requesters ID
         * @returns                                     
@@ -85,20 +76,16 @@ struct mediation_manager_t {
                        identification_t *peer_id, identification_t *requester);
        
        /**
-        * @brief Destroys the manager with all data.
-        * 
-        * @param this                           the manager object
+        * Destroys the manager with all data.
         */
        void (*destroy) (mediation_manager_t *this);
 };
 
 /**
- * @brief Create a manager.
+ * Create a manager.
  * 
  * @returns    mediation_manager_t object
- * 
- * @ingroup sa
  */
 mediation_manager_t *mediation_manager_create(void);
 
-#endif /*MEDIATION_MANAGER_H_*/
+#endif /*MEDIATION_MANAGER_H_ @} */
index 89f527abaac2e0d27fb34d1aec0a52c28d9a27f3..df06970555be85800762582448b1be995a46d45a 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file task_manager.c
- *
- * @brief Implementation of task_manager_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2007 Martin Willi
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "task_manager.h"
@@ -31,7 +26,8 @@
 #include <sa/tasks/ike_mobike.h>
 #include <sa/tasks/ike_auth.h>
 #include <sa/tasks/ike_auth_lifetime.h>
-#include <sa/tasks/ike_cert.h>
+#include <sa/tasks/ike_cert_pre.h>
+#include <sa/tasks/ike_cert_post.h>
 #include <sa/tasks/ike_rekey.h>
 #include <sa/tasks/ike_delete.h>
 #include <sa/tasks/ike_config.h>
@@ -328,7 +324,7 @@ static status_t build_request(private_task_manager_t *this)
                                        this->initiating.mid = 0;
                                        exchange = IKE_SA_INIT;
                                        activate_task(this, IKE_NATD);
-                                       activate_task(this, IKE_CERT);
+                                       activate_task(this, IKE_CERT_PRE);
 #ifdef P2P
                                        /* this task has to be activated before the IKE_AUTHENTICATE
                                         * task, because that task pregenerates the packet after
@@ -337,6 +333,7 @@ static status_t build_request(private_task_manager_t *this)
                                        activate_task(this, IKE_P2P);
 #endif /* P2P */
                                        activate_task(this, IKE_AUTHENTICATE);
+                                       activate_task(this, IKE_CERT_POST);
                                        activate_task(this, IKE_CONFIG);
                                        activate_task(this, CHILD_CREATE);
                                        activate_task(this, IKE_AUTH_LIFETIME);
@@ -687,7 +684,7 @@ static status_t process_request(private_task_manager_t *this,
                        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_create(this->ike_sa, FALSE);
+                       task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
                        this->passive_tasks->insert_last(this->passive_tasks, task);
 #ifdef P2P                     
                        task = (task_t*)ike_p2p_create(this->ike_sa, FALSE);
@@ -695,6 +692,8 @@ static status_t process_request(private_task_manager_t *this,
 #endif /* P2P */
                        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);
index 38c63c1a9ec9b2a12c992ad159de080322134ad3..07cd8f55783bc725e5fd178d338b9edf1c797781 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file task_manager.h
- * 
- * @brief Interface of task_manager_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 task_manager task_manager
+ * @{ @ingroup sa
  */
 
 #ifndef TASK_MANAGER_H_
@@ -32,42 +32,32 @@ typedef struct task_manager_t task_manager_t;
 
 /**
  * First retransmit timeout in milliseconds.
- *
- * @ingroup sa
  */
 #define RETRANSMIT_TIMEOUT 4000
 
 /**
  * Base which is raised to the power of the retransmission try.
- *
- * @ingroup sa
  */
 #define RETRANSMIT_BASE 1.8
 
 /**
  * Number of retransmits done before giving up.
- *
- * @ingroup sa
  */
 #define RETRANSMIT_TRIES 5
 
 /**
  * Interval for mobike routability checks in ms.
- *
- * @ingroup sa
  */
 #define ROUTEABILITY_CHECK_INTERVAL 2500
 
 /**
  * Number of routability checks before giving up
- * 
- * @ingroup sa
  */
 #define ROUTEABILITY_CHECK_TRIES 10
 
 
 /**
- * @brief The task manager, juggles task and handles message exchanges.
+ * The task manager, juggles task and handles message exchanges.
  *
  * On incoming requests, the task manager creates new tasks on demand and
  * juggles the request through all available tasks. Each task inspects the
@@ -97,18 +87,12 @@ typedef struct task_manager_t task_manager_t;
  
    @endberbatim
  * The peer is considered dead after 2min 45s when no reply comes in.
- *
- * @b Constructors:
- *  - task_manager_create()
- * 
- * @ingroup sa
  */
 struct task_manager_t {
 
        /**
-        * @brief Process an incoming message.
+        * Process an incoming message.
         * 
-        * @param this                  calling object
         * @param message               message to add payloads to
         * @return
         *                                              - DESTROY_ME if IKE_SA must be closed
@@ -117,28 +101,24 @@ struct task_manager_t {
        status_t (*process_message) (task_manager_t *this, message_t *message);
 
        /**
-        * @brief Initiate an exchange with the currently queued tasks.
-        *
-        * @param this                  calling object
+        * Initiate an exchange with the currently queued tasks.
         */
        status_t (*initiate) (task_manager_t *this);
 
        /**
-        * @brief Queue a task in the manager.
+        * Queue a task in the manager.
         *
-        * @param this                  calling object
         * @param task                  task to queue
         */
        void (*queue_task) (task_manager_t *this, task_t *task);
 
        /**
-        * @brief Retransmit a request if it hasn't been acknowledged yet.
+        * Retransmit a request if it hasn't been acknowledged yet.
         *
         * A return value of INVALID_STATE means that the message was already
         * acknowledged and has not to be retransmitted. A return value of SUCCESS
         * means retransmission was required and the message has been resent.
         * 
-        * @param this                  calling object
         * @param message_id    ID of the message to retransmit
         * @return
         *                                              - INVALID_STATE if retransmission not required
@@ -147,52 +127,45 @@ struct task_manager_t {
        status_t (*retransmit) (task_manager_t *this, u_int32_t message_id);
 
        /**
-        * @brief Migrate all tasks from other to this.
+        * Migrate all tasks from other to this.
         *
         * To rekey or reestablish an IKE_SA completely, all queued or active
         * tasks should get migrated to the new IKE_SA.
         * 
-        * @param this                  manager which gets all tasks
         * @param other                 manager which gives away its tasks
         */
        void (*adopt_tasks) (task_manager_t *this, task_manager_t *other);
        
        /**
-        * @brief Reset message ID counters of the task manager.
+        * Reset message ID counters of the task manager.
         *
         * The IKEv2 protocol requires to restart exchanges with message IDs
         * reset to zero (INVALID_KE_PAYLOAD, COOKIES, ...). The reset() method
         * resets the message IDs and resets all active tasks using the migrate()
         * method.
         * 
-        * @param this                  calling object
         * @param other                 manager which gives away its tasks
         */
        void (*reset) (task_manager_t *this);
        
        /**
-        * @brief Check if we are currently waiting for a reply.
+        * Check if we are currently waiting for a reply.
         *
-        * @param this                  calling object
         * @return                              TRUE if we are waiting, FALSE otherwise
         */
        bool (*busy) (task_manager_t *this);
        
        /**
-        * @brief Destroy the task_manager_t.
-        *
-        * @param this                  calling object
+        * Destroy the task_manager_t.
         */
        void (*destroy) (task_manager_t *this);
 };
 
 /**
- * @brief Create an instance of the task manager.
+ * Create an instance of the task manager.
  *
  * @param ike_sa               IKE_SA to manage.
- *
- * @ingroup sa
  */
 task_manager_t *task_manager_create(ike_sa_t *ike_sa);
 
-#endif /* TASK_MANAGER_H_ */
+#endif /* TASK_MANAGER_H_ @} */
index 3947a84d1415de21806e1f2a582fd7ef3c807113..d933d626744693978fd5f51de570ef39931feb44 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_create.c
- *
- * @brief Implementation of the child_create task.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "child_create.h"
@@ -450,7 +445,7 @@ static void process_payloads(private_child_create_t *this, message_t *message)
                                if (!this->initiator)
                                {
                                        this->dh_group = ke_payload->get_dh_group_number(ke_payload);
-                                       this->dh = diffie_hellman_create(this->dh_group);
+                                       this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
                                }
                                if (this->dh)
                                {
@@ -580,7 +575,7 @@ static status_t build_i(private_child_create_t *this, message_t *message)
        
        if (this->dh_group != MODP_NONE)
        {
-               this->dh = diffie_hellman_create(this->dh_group);
+               this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
        }
        
        build_payloads(this, message);
index 9f4815215485d4a94869101d1e804f7a649694f1..1a14cd5f9e87d9ed6c5d89831d1d9f86ca9a6e98 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_create.h
- * 
- * @brief Interface child_create_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 child_create child_create
+ * @{ @ingroup tasks
  */
 
 #ifndef CHILD_CREATE_H_
@@ -31,15 +31,10 @@ typedef struct child_create_t child_create_t;
 #include <config/child_cfg.h>
 
 /**
- * @brief Task of type CHILD_CREATE, established a new CHILD_SA.
+ * Task of type CHILD_CREATE, established a new CHILD_SA.
  *
  * This task may be included in the IKE_AUTH message or in a separate 
  * CREATE_CHILD_SA exchange.
- *
- * @b Constructors:
- *  - child_create_create()
- * 
- * @ingroup tasks
  */
 struct child_create_t {
 
@@ -49,35 +44,32 @@ struct child_create_t {
        task_t task;
        
        /**
-        * @brief Use a specific reqid for the CHILD_SA.
+        * Use a specific reqid for the CHILD_SA.
         *
         * When this task is used for rekeying, the same reqid is used
         * for the new CHILD_SA. 
         *
-        * @param this          calling object
         * @param reqid         reqid to use
         */
        void (*use_reqid) (child_create_t *this, u_int32_t reqid);
        
        /**
-        * @brief Get the lower of the two nonces, used for rekey collisions.
+        * Get the lower of the two nonces, used for rekey collisions.
         *
-        * @param this          calling object
         * @return                      lower nonce
         */
        chunk_t (*get_lower_nonce) (child_create_t *this);
        
        /**
-        * @brief Get the CHILD_SA established/establishing by this task.
+        * Get the CHILD_SA established/establishing by this task.
         *
-        * @param this          calling object
         * @return                      child_sa
         */
        child_sa_t* (*get_child) (child_create_t *this);
 };
 
 /**
- * @brief Create a new child_create task.
+ * Create a new child_create task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param config               child_cfg if task initiator, NULL if responder
@@ -85,4 +77,4 @@ struct child_create_t {
  */
 child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config);
 
-#endif /* CHILD_CREATE_H_ */
+#endif /* CHILD_CREATE_H_ @} */
index d0b34a276fa18f3530acf8e790f148ba56fafb78..2c1db2ad01b890e9e734d21104c8d7bdab2535fc 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_delete.c
- *
- * @brief Implementation of the child_delete task.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "child_delete.h"
index a7e676a50f4e6c1e59282aec6a80bd11691a9012..1aa60993e68003f58b61d6f2bf8e1a9c88cffaaf 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_delete.h
- * 
- * @brief Interface child_delete_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 child_delete child_delete
+ * @{ @ingroup tasks
  */
 
 #ifndef CHILD_DELETE_H_
@@ -31,12 +31,7 @@ typedef struct child_delete_t child_delete_t;
 #include <sa/child_sa.h>
 
 /**
- * @brief Task of type child_delete, delete a CHILD_SA.
- *
- * @b Constructors:
- *  - child_delete_create()
- * 
- * @ingroup tasks
+ * Task of type child_delete, delete a CHILD_SA.
  */
 struct child_delete_t {
 
@@ -46,16 +41,15 @@ struct child_delete_t {
        task_t task;
        
        /**
-        * @brief Get the CHILD_SA to delete by this task.
+        * Get the CHILD_SA to delete by this task.
         *
-        * @param this          calling object
         * @return                      child_sa
         */
        child_sa_t* (*get_child) (child_delete_t *this);
 };
 
 /**
- * @brief Create a new child_delete task.
+ * Create a new child_delete task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param child_sa             CHILD_SA to delete, or NULL as responder
@@ -63,4 +57,4 @@ struct child_delete_t {
  */
 child_delete_t *child_delete_create(ike_sa_t *ike_sa, child_sa_t *child_sa);
 
-#endif /* CHILD_DELETE_H_ */
+#endif /* CHILD_DELETE_H_ @} */
index 3667d8fada3a338eb9bef0272589f2c6b06d6d92..6d741b76000216d26ab69714a210ea6fd64d7b8a 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_rekey.c
- *
- * @brief Implementation of the child_rekey task.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "child_rekey.h"
index 3515f0c3fd600283b5f839b8b21261a28c09bd0d..382cf4a31c5e6fcb5ecb7693b2ce6d83f802c906 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file child_rekey.h
- * 
- * @brief Interface child_rekey_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 child_rekey child_rekey
+ * @{ @ingroup tasks
  */
 
 #ifndef CHILD_REKEY_H_
@@ -31,12 +31,7 @@ typedef struct child_rekey_t child_rekey_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type CHILD_REKEY, rekey an established CHILD_SA.
- *
- * @b Constructors:
- *  - child_rekey_create()
- * 
- * @ingroup tasks
+ * Task of type CHILD_REKEY, rekey an established CHILD_SA.
  */
 struct child_rekey_t {
 
@@ -46,20 +41,19 @@ struct child_rekey_t {
        task_t task;
        
        /**
-        * @brief Register a rekeying task which collides with this one
+        * Register a rekeying task which collides with this one
         *
         * If two peers initiate rekeying at the same time, the collision must
         * be handled gracefully. The task manager is aware of what exchanges
         * are going on and notifies the outgoing task by passing the incoming.
         *
-        * @param this          task initated by us
         * @param other         incoming task
         */
        void (*collide)(child_rekey_t* this, task_t *other);
 };
 
 /**
- * @brief Create a new CHILD_REKEY task.
+ * Create a new CHILD_REKEY task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param child_sa             child_sa to rekey, NULL if responder
@@ -67,4 +61,4 @@ struct child_rekey_t {
  */
 child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, child_sa_t *child_sa);
 
-#endif /* CHILD_REKEY_H_ */
+#endif /* CHILD_REKEY_H_ @} */
index de88a0abea5cb31881713de8478aa7e641c20391..11382047a773217b51dc541edfd87de216a14a70 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_auth.c
- *
- * @brief Implementation of the ike_auth task.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -18,7 +11,9 @@
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
+ * for more details
+ *
+ * $Id$
  */
 
 #include "ike_auth.h"
@@ -231,7 +226,7 @@ static status_t process_id(private_ike_auth_t *this, message_t *message)
        {
                id = idr->get_identification(idr);
                req = this->ike_sa->get_other_id(this->ike_sa);
-               if (!id->matches(id, req, NULL))
+               if (!id->matches(id, req))
                {
                        SIG(IKE_UP_FAILED, "peer ID %D unacceptable, %D required", id, req);
                        id->destroy(id);
@@ -525,13 +520,13 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
                        this->eap_auth = eap_authenticator_create(this->ike_sa);
                        break;
                default:
-                       break;
+                       return NEED_MORE;
        }
 
        config = charon->backends->get_peer_cfg(charon->backends,
                                                                        this->ike_sa->get_my_id(this->ike_sa),
                                                                        this->ike_sa->get_other_id(this->ike_sa),
-                                                                       this->ike_sa->get_other_ca(this->ike_sa));
+                                                                       this->ike_sa->get_other_auth(this->ike_sa));
        if (config)
        {
                this->ike_sa->set_peer_cfg(this->ike_sa, config);
@@ -557,6 +552,13 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
                return collect_my_init_data(this, message);
        }
        
+       if (!this->peer_authenticated && this->eap_auth == 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)
        {
@@ -587,13 +589,6 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
                return SUCCESS;
        }
        
-       if (this->eap_auth == NULL)
-       {
-               /* peer not authenticated, nor does it want to use EAP */
-               message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
-               return FAILED;
-       }
-       
        /* initiate EAP authenitcation */
        eap_type = config->get_eap_type(config, &eap_vendor);
        status = this->eap_auth->initiate(this->eap_auth, eap_type,
@@ -618,6 +613,8 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
 {
        iterator_t *iterator;
        payload_t *payload;
+       peer_cfg_t *config;
+       auth_info_t *auth;
        
        if (message->get_exchange_type(message) == IKE_SA_INIT)
        {
@@ -687,10 +684,18 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
                return process_eap_i(this, message);
        }
        
+       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)))
+       {
+               SIG(IKE_UP_FAILED, "authorization of %D for config %s failed",
+                       this->ike_sa->get_other_id(this->ike_sa), config->get_name(config));
+               return FAILED;
+       }
        this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
        SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %D[%H]...[%H]%D",
                this->ike_sa->get_name(this->ike_sa),
-               this->ike_sa->get_my_id(this->ike_sa), 
+               this->ike_sa->get_my_id(this->ike_sa),
                this->ike_sa->get_my_host(this->ike_sa),
                this->ike_sa->get_other_host(this->ike_sa),
                this->ike_sa->get_other_id(this->ike_sa));
index d7326c9884ddc4f5ba40da03e16928e054419b2a..f44aa7ce6e857f3fbbc303a4f302378d9ee88942 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_auth.h
- * 
- * @brief Interface ike_auth_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_auth ike_auth
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_AUTH_H_
@@ -30,7 +30,7 @@ typedef struct ike_auth_t ike_auth_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type ike_auth, authenticates an IKE_SA using authenticators.
+ * Task of type ike_auth, authenticates an IKE_SA using authenticators.
  *
  * The ike_auth task authenticates the IKE_SA using the IKE_AUTH
  * exchange. It processes and build IDi and IDr payloads and also
@@ -38,11 +38,6 @@ typedef struct ike_auth_t ike_auth_t;
  * which do the actual authentication process. If the ike_auth task is used
  * with EAP authentication, it stays alive over multiple exchanges until
  * EAP has completed.
- *
- * @b Constructors:
- *  - ike_auth_create()
- * 
- * @ingroup tasks
  */
 struct ike_auth_t {
 
@@ -53,7 +48,7 @@ struct ike_auth_t {
 };
 
 /**
- * @brief Create a new task of type IKE_AUTHENTICATE.
+ * Create a new task of type IKE_AUTHENTICATE.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param initiator            TRUE if thask is the initator of an exchange
@@ -61,4 +56,4 @@ struct ike_auth_t {
  */
 ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator);
 
-#endif /* IKE_AUTH_H_ */
+#endif /* IKE_AUTH_H_ @} */
index 9d37ec60883c14bb1d538477ffcc0839d7d707c0..969e21c2bd7a27cbc5886fac1942061523e85372 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_auth_lifetime.c
- *
- * @brief Implementation of the ike_auth_lifetime task.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "ike_auth_lifetime.h"
index 500b89d39bbc569966491b625702c6a7d43a4b27..df69ce29cb38ae42dd712ba52570eeb6e511dc79 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_auth_lifetime.h
- * 
- * @brief Interface ike_auth_lifetime_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_auth_lifetime ike_auth_lifetime
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_AUTH_LIFETIME_H_
@@ -30,15 +30,10 @@ typedef struct ike_auth_lifetime_t ike_auth_lifetime_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type IKE_AUTH_LIFETIME, implements RFC4478.
+ * Task of type IKE_AUTH_LIFETIME, implements RFC4478.
  *
  * This task exchanges lifetimes for IKE_AUTH to force a client to 
  * reauthenticate before the responders lifetime reaches the limit.
- *
- * @b Constructors:
- *  - ike_auth_lifetime_create()
- * 
- * @ingroup tasks
  */
 struct ike_auth_lifetime_t {
 
@@ -49,7 +44,7 @@ struct ike_auth_lifetime_t {
 };
 
 /**
- * @brief Create a new IKE_AUTH_LIFETIME task.
+ * Create a new IKE_AUTH_LIFETIME task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param initiator            TRUE if taks is initiated by us
@@ -57,5 +52,4 @@ struct ike_auth_lifetime_t {
  */
 ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator);
 
-#endif /* IKE_MOBIKE_H_ */
-
+#endif /* IKE_MOBIKE_H_ @} */
diff --git a/src/charon/sa/tasks/ike_cert.c b/src/charon/sa/tasks/ike_cert.c
deleted file mode 100644 (file)
index 880ed9c..0000000
+++ /dev/null
@@ -1,366 +0,0 @@
-/**
- * @file ike_cert.c
- *
- * @brief Implementation of the ike_cert task.
- *
- */
-
-/*
- * Copyright (C) 2006-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 "ike_cert.h"
-
-#include <daemon.h>
-#include <sa/ike_sa.h>
-#include <crypto/hashers/hasher.h>
-#include <encoding/payloads/cert_payload.h>
-#include <encoding/payloads/certreq_payload.h>
-
-
-typedef struct private_ike_cert_t private_ike_cert_t;
-
-/**
- * Private members of a ike_cert_t task.
- */
-struct private_ike_cert_t {
-       
-       /**
-        * Public methods and task_t interface.
-        */
-       ike_cert_t public;
-       
-       /**
-        * Assigned IKE_SA.
-        */
-       ike_sa_t *ike_sa;
-       
-       /**
-        * Are we the initiator?
-        */
-       bool initiator;
-       
-       /**
-        * list of CA cert hashes requested, items point to 20 byte chunk
-        */
-       linked_list_t *cas;
-       
-       /** 
-        * have we seen a certificate request?
-        */
-       bool certreq_seen;
-};
-
-/**
- * read certificate requests 
- */
-static void process_certreqs(private_ike_cert_t *this, message_t *message)
-{
-       iterator_t *iterator;
-       payload_t *payload;
-       
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
-       {
-               if (payload->get_type(payload) == CERTIFICATE_REQUEST)
-               {
-                       certreq_payload_t *certreq = (certreq_payload_t*)payload;
-                       cert_encoding_t encoding;
-                       chunk_t keyids, keyid;
-                       
-                       this->certreq_seen = TRUE;
-                       
-                       encoding = certreq->get_cert_encoding(certreq);
-                       if (encoding != CERT_X509_SIGNATURE)
-                       {
-                               DBG1(DBG_IKE, "certreq payload %N not supported - ignored",
-                                        cert_encoding_names, encoding);
-                               continue;
-                       }
-
-                       keyids = certreq->get_data(certreq);
-                                       
-                       while (keyids.len >= HASH_SIZE_SHA1)
-                       {
-                               keyid = chunk_create(keyids.ptr, HASH_SIZE_SHA1);
-                               keyid = chunk_clone(keyid);
-                               this->cas->insert_last(this->cas, keyid.ptr);
-                               keyids = chunk_skip(keyids, HASH_SIZE_SHA1);
-                       }
-               }
-       }
-       iterator->destroy(iterator);
-}
-
-/**
- * import certificates
- */
-static void process_certs(private_ike_cert_t *this, message_t *message)
-{
-       iterator_t *iterator;
-       payload_t *payload;
-       
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
-       {
-               if (payload->get_type(payload) == CERTIFICATE)
-               {
-                       cert_encoding_t encoding;
-                       x509_t *cert;
-                       chunk_t cert_data;
-                       bool found;
-                       cert_payload_t *cert_payload = (cert_payload_t*)payload;
-                       
-                       encoding = cert_payload->get_cert_encoding(cert_payload);
-                       if (encoding != CERT_X509_SIGNATURE)
-                       {
-                               DBG1(DBG_IKE, "certificate payload %N not supported - ignored",
-                                        cert_encoding_names, encoding);
-                               continue;
-                       }
-                       
-                       cert_data = cert_payload->get_data_clone(cert_payload);
-                       cert = x509_create_from_chunk(cert_data, 0);
-                       if (cert)
-                       {
-                               if (charon->credentials->verify(charon->credentials, cert, &found))
-                               {
-                                       DBG2(DBG_IKE, "received end entity certificate is trusted - "
-                                                                 "added to store");
-                                       if (found)
-                                       {
-                                               cert->destroy(cert);
-                                       }
-                                       else
-                                       {
-                                               charon->credentials->add_end_certificate(charon->credentials, cert);
-                                       }
-                               }
-                               else
-                               {
-                                       DBG1(DBG_IKE, "received end entity certificate is not trusted - "
-                                                                 "discarded");
-                                       cert->destroy(cert);
-                               }
-                       }
-                       else
-                       {
-                               DBG1(DBG_IKE, "parsing of received certificate failed - discarded");
-                               chunk_free(&cert_data);
-                       }
-               }
-       }
-       iterator->destroy(iterator);
-}
-
-/**
- * build certificate requests
- */
-static void build_certreqs(private_ike_cert_t *this, message_t *message)
-{
-       ike_cfg_t *ike_cfg;
-       peer_cfg_t *peer_cfg;
-       identification_t *ca;
-       certreq_payload_t *certreq;
-       
-       ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
-       
-       if (ike_cfg->send_certreq(ike_cfg) != CERT_NEVER_SEND)
-       {       
-               peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-               
-               if (peer_cfg)
-               {
-                       ca = peer_cfg->get_other_ca(peer_cfg);
-                       
-                       if (ca && ca->get_type(ca) != ID_ANY)
-                       {
-                               certreq = certreq_payload_create_from_cacert(ca);
-                       }
-                       else
-                       {
-                               certreq = certreq_payload_create_from_cacerts();
-                       }
-               }
-               else
-               {
-                       certreq = certreq_payload_create_from_cacerts();
-               }
-               
-               if (certreq)
-               {
-                       message->add_payload(message, (payload_t*)certreq);
-               }
-       }
-}
-
-/**
- * add certificates to message
- */
-static void build_certs(private_ike_cert_t *this, message_t *message)
-{
-       peer_cfg_t *peer_cfg;
-       x509_t *cert;
-       cert_payload_t *payload;
-       
-       peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-
-       if (peer_cfg && peer_cfg->get_auth_method(peer_cfg) == AUTH_RSA)
-       {
-               switch (peer_cfg->get_cert_policy(peer_cfg))
-               {
-                       case CERT_NEVER_SEND:
-                               break;
-                       case CERT_SEND_IF_ASKED:
-                               if (!this->certreq_seen)
-                               {
-                                       break;
-                               }
-                               /* FALL */
-                       case CERT_ALWAYS_SEND:
-                       {
-                               /* TODO: respect CA cert request */
-                               cert = charon->credentials->get_certificate(charon->credentials,
-                                                                                               peer_cfg->get_my_id(peer_cfg));
-                               if (cert)
-                               {
-                                       payload = cert_payload_create_from_x509(cert);
-                                       message->add_payload(message, (payload_t*)payload);
-                               }
-                       }       
-               }
-       }
-}
-
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_cert_t *this, message_t *message)
-{
-       if (message->get_exchange_type(message) == IKE_SA_INIT)
-       {
-               return NEED_MORE;
-       }
-               
-       build_certreqs(this, message);
-       build_certs(this, message);
-       
-       return NEED_MORE;
-}
-
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_cert_t *this, message_t *message)
-{      
-       if (message->get_exchange_type(message) == IKE_SA_INIT)
-       {
-               return NEED_MORE;
-       }
-       
-       process_certreqs(this, message);
-       process_certs(this, message);
-       
-       return NEED_MORE;
-}
-
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_cert_t *this, message_t *message)
-{
-       if (message->get_exchange_type(message) == IKE_SA_INIT)
-       {
-               build_certreqs(this, message);
-               return NEED_MORE;
-       }
-       
-       build_certs(this, message);
-       
-       return SUCCESS;
-}
-
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_cert_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;
-}
-
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_cert_t *this)
-{
-       return IKE_CERT;
-}
-
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_cert_t *this, ike_sa_t *ike_sa)
-{
-       this->ike_sa = ike_sa;
-       
-       this->cas->destroy_function(this->cas, free);
-       this->cas = linked_list_create();
-       this->certreq_seen = FALSE;
-}
-
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_cert_t *this)
-{
-       this->cas->destroy_function(this->cas, free);
-       free(this);
-}
-
-/*
- * Described in header.
- */
-ike_cert_t *ike_cert_create(ike_sa_t *ike_sa, bool initiator)
-{
-       private_ike_cert_t *this = malloc_thing(private_ike_cert_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;
-       
-       if (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->ike_sa = ike_sa;
-       this->initiator = initiator;
-       this->cas = linked_list_create();
-       this->certreq_seen = FALSE;
-       
-       return &this->public;
-}
diff --git a/src/charon/sa/tasks/ike_cert_post.c b/src/charon/sa/tasks/ike_cert_post.c
new file mode 100644 (file)
index 0000000..a3cad0b
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2006-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.
+ *
+ * $Id$
+ */
+
+#include "ike_cert_post.h"
+
+#include <daemon.h>
+#include <sa/ike_sa.h>
+#include <encoding/payloads/cert_payload.h>
+#include <encoding/payloads/certreq_payload.h>
+#include <credentials/certificates/x509.h>
+
+
+typedef struct private_ike_cert_post_t private_ike_cert_post_t;
+
+/**
+ * Private members of a ike_cert_post_t task.
+ */
+struct private_ike_cert_post_t {
+       
+       /**
+        * Public methods and task_t interface.
+        */
+       ike_cert_post_t public;
+       
+       /**
+        * Assigned IKE_SA.
+        */
+       ike_sa_t *ike_sa;
+       
+       /**
+        * Are we the initiator?
+        */
+       bool initiator;
+};
+
+/**
+ * add certificates to message
+ */
+static void build_certs(private_ike_cert_post_t *this, message_t *message)
+{
+       peer_cfg_t *peer_cfg;
+       
+       peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+       if (peer_cfg && peer_cfg->get_auth_method(peer_cfg) == AUTH_RSA)
+       {
+               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:
+                       {
+                               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 = cert_payload_create_from_cert(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))
+                               {
+                                       if (item == AUTHZ_IM_CERT)
+                                       {
+                                               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);
+                                               }
+                                       }
+                               }
+                               enumerator->destroy(enumerator);
+                       }       
+               }
+       }
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+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;
+}
+
+/**
+ * Implementation of task_t.process for responder
+ */
+static status_t process_r(private_ike_cert_post_t *this, message_t *message)
+{      
+       return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.build for responder
+ */
+static status_t build_r(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;
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+static status_t process_i(private_ike_cert_post_t *this, message_t *message)
+{
+       if (message->get_exchange_type(message) == IKE_SA_INIT)
+       {
+               return NEED_MORE;
+       }
+       return SUCCESS;
+}
+
+/**
+ * Implementation of task_t.get_type
+ */
+static task_type_t get_type(private_ike_cert_post_t *this)
+{
+       return IKE_CERT_POST;
+}
+
+/**
+ * Implementation of task_t.migrate
+ */
+static void migrate(private_ike_cert_post_t *this, ike_sa_t *ike_sa)
+{
+       this->ike_sa = ike_sa;
+}
+
+/**
+ * Implementation of task_t.destroy
+ */
+static void destroy(private_ike_cert_post_t *this)
+{
+       free(this);
+}
+
+/*
+ * Described in header.
+ */
+ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator)
+{
+       private_ike_cert_post_t *this = malloc_thing(private_ike_cert_post_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;
+       
+       if (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->ike_sa = ike_sa;
+       this->initiator = initiator;
+       
+       return &this->public;
+}
+
similarity index 64%
rename from src/charon/sa/tasks/ike_cert.h
rename to src/charon/sa/tasks/ike_cert_post.h
index ba028395355bebd19c16a99e42124aba091185fb..3291d9ab3d40fd5372fb0094a0356f753690b216 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file ike_cert.h
- * 
- * @brief Interface ike_cert_t.
- * 
- */
-
 /*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 IKE_CERT_H_
-#define IKE_CERT_H_
+/**
+ * @defgroup ike_cert_post ike_cert_post
+ * @{ @ingroup tasks
+ */
 
-typedef struct ike_cert_t ike_cert_t;
+#ifndef IKE_CERT_POST_H_
+#define IKE_CERT_POST_H_
+
+typedef struct ike_cert_post_t ike_cert_post_t;
 
 #include <library.h>
 #include <sa/ike_sa.h>
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type ike_cert, exchanges certificates and 
- * certificate requests.
- *
- * @b Constructors:
- *  - ike_cert_create()
- * 
- * @ingroup tasks
+ * Task of type ike_cert_post, certificate processing after authentication.
  */
-struct ike_cert_t {
+struct ike_cert_post_t {
 
        /**
         * Implements the task_t interface
@@ -47,15 +41,15 @@ struct ike_cert_t {
 };
 
 /**
- * @brief Create a new ike_cert task.
+ * Create a new ike_cert_post task.
  *
  * The initiator parameter means the original initiator, not the initiator
  * of the certificate request.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param initiator            TRUE if thask is the original initator
- * @return                             ike_cert task to handle by the task_manager
+ * @return                             ike_cert_post task to handle by the task_manager
  */
-ike_cert_t *ike_cert_create(ike_sa_t *ike_sa, bool initiator);
+ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator);
 
-#endif /* IKE_CERT_H_ */
+#endif /*  IKE_CERT_POST_H_ @} */
diff --git a/src/charon/sa/tasks/ike_cert_pre.c b/src/charon/sa/tasks/ike_cert_pre.c
new file mode 100644 (file)
index 0000000..aa1cfb1
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2006-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$
+ */
+
+#include "ike_cert_pre.h"
+
+#include <daemon.h>
+#include <sa/ike_sa.h>
+#include <encoding/payloads/cert_payload.h>
+#include <encoding/payloads/certreq_payload.h>
+#include <credentials/certificates/x509.h>
+
+
+typedef struct private_ike_cert_pre_t private_ike_cert_pre_t;
+
+/**
+ * Private members of a ike_cert_pre_t task.
+ */
+struct private_ike_cert_pre_t {
+       
+       /**
+        * Public methods and task_t interface.
+        */
+       ike_cert_pre_t public;
+       
+       /**
+        * Assigned IKE_SA.
+        */
+       ike_sa_t *ike_sa;
+       
+       /**
+        * Are we the initiator?
+        */
+       bool initiator;
+};
+
+/**
+ * read certificate requests 
+ */
+static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
+{
+       iterator_t *iterator;
+       payload_t *payload;
+       auth_info_t *auth;
+       bool ca_found = FALSE;
+       
+       auth = this->ike_sa->get_my_auth(this->ike_sa);
+       
+       iterator = message->get_payload_iterator(message);
+       while (iterator->iterate(iterator, (void**)&payload))
+       {
+               if (payload->get_type(payload) == CERTIFICATE_REQUEST)
+               {
+                       certreq_payload_t *certreq = (certreq_payload_t*)payload;
+                       chunk_t keyid;
+                       enumerator_t *enumerator;
+                       
+                       this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE);
+                       
+                       if (certreq->get_cert_type(certreq) != CERT_X509)
+                       {
+                               DBG1(DBG_IKE, "cert payload %N not supported - ignored",
+                                        certificate_type_names, certreq->get_cert_type(certreq));
+                               continue;
+                       }
+                       enumerator = certreq->create_keyid_enumerator(certreq);
+                       while (enumerator->enumerate(enumerator, &keyid))
+                       {
+                               identification_t *id;
+                               certificate_t *cert;
+                               
+                               id = identification_create_from_encoding(
+                                                                               ID_PUBKEY_INFO_SHA1, keyid);
+                               cert = charon->credentials->get_cert(charon->credentials, 
+                                                                               CERT_X509, KEY_ANY, id, TRUE);
+                               if (cert)
+                               {
+                                       DBG1(DBG_IKE, "received cert request for %D",
+                                                cert->get_subject(cert));
+                                       auth->add_item(auth, AUTHN_CA_CERT, cert);
+                                       cert->destroy(cert);
+                                       ca_found = TRUE;
+                               }
+                               id->destroy(id);
+                       }
+                       enumerator->destroy(enumerator);
+               }
+       }
+       iterator->destroy(iterator);
+       
+       if (this->ike_sa->has_condition(this->ike_sa, COND_CERTREQ_SEEN) && !ca_found)
+       {
+               DBG1(DBG_IKE, "received cert request, but no such CA cert found");
+       }
+}
+
+/**
+ * import certificates
+ */
+static void process_certs(private_ike_cert_pre_t *this, message_t *message)
+{
+       iterator_t *iterator;
+       payload_t *payload;
+       auth_info_t *auth;
+       bool first = TRUE;
+       
+       auth = this->ike_sa->get_other_auth(this->ike_sa);
+       
+       iterator = message->get_payload_iterator(message);
+       while (iterator->iterate(iterator, (void**)&payload))
+       {
+               if (payload->get_type(payload) == CERTIFICATE)
+               {
+                       certificate_t *cert;
+                       cert_payload_t *cert_payload = (cert_payload_t*)payload;
+                       
+                       cert = cert_payload->get_cert(cert_payload);
+                       if (cert)
+                       {
+                               if (first)
+                               {       /* the first certificate MUST be an end entity one */
+                               
+                                       DBG1(DBG_IKE, "received end entity cert %D",
+                                                cert->get_subject(cert));
+                                       auth->add_item(auth, AUTHN_SUBJECT_CERT, cert);
+                                       first = FALSE;
+                               }
+                               else
+                               {
+                                       DBG1(DBG_IKE, "received issuer cert %D",
+                                                cert->get_subject(cert));
+                                       auth->add_item(auth, AUTHN_IM_CERT, cert);
+                               }
+                       }
+                       cert->destroy(cert);
+               }
+       }
+       iterator->destroy(iterator);
+}
+
+/**
+ * add a certificate request to the message, building request payload if required.
+ */
+static void add_certreq_payload(message_t *message, certreq_payload_t **reqp, 
+                                                               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:
+               {
+                       identification_t *keyid;
+                       x509_t *x509 = (x509_t*)cert;
+                       
+                       if (!(x509->get_flags(x509) & X509_CA))
+                       {       /* no CA cert, skip */
+                               break;
+                       }
+                       if (*reqp == NULL)
+                       {
+                               *reqp = certreq_payload_create_type(CERT_X509);
+                               message->add_payload(message, (payload_t*)*reqp);
+                       }
+                       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",
+                                cert->get_subject(cert));
+                       break;
+               }
+               default:
+                       break;
+       }
+       public->destroy(public);
+}
+
+/**
+ * build certificate requests
+ */
+static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
+{
+       ike_cfg_t *ike_cfg;
+       enumerator_t *enumerator;
+       certificate_t *cert;
+       auth_info_t *auth;
+       bool restricted = FALSE;
+       auth_item_t item;
+       certreq_payload_t *x509_req = NULL;
+       
+       ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
+       if (ike_cfg->send_certreq(ike_cfg) == CERT_NEVER_SEND)
+       {
+               return;
+       }
+       auth = this->ike_sa->get_other_auth(this->ike_sa);
+
+       /* check if we require a specific CA for that peer */
+       enumerator = auth->create_item_enumerator(auth);
+       while (enumerator->enumerate(enumerator, &item, &cert))
+       {
+               if (item == AUTHN_CA_CERT)
+               {
+                       restricted = TRUE;
+                       add_certreq_payload(message, &x509_req, cert);
+               }
+       }
+       enumerator->destroy(enumerator);
+               
+       if (!restricted)
+       {
+               /* otherwise include all trusted CA certificates */
+               enumerator = charon->credentials->create_cert_enumerator(
+                                                       charon->credentials, CERT_ANY, KEY_ANY, NULL, TRUE);
+               while (enumerator->enumerate(enumerator, &cert, TRUE))
+               {
+                       add_certreq_payload(message, &x509_req, cert);
+               }
+               enumerator->destroy(enumerator);
+       }
+}
+
+/**
+ * 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;
+       }
+       build_certreqs(this, message);
+       return NEED_MORE;
+}
+
+/**
+ * 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;
+       }
+       process_certreqs(this, message);
+       process_certs(this, message);
+       return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.build for responder
+ */
+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;
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+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;
+}
+
+/**
+ * Implementation of task_t.get_type
+ */
+static task_type_t get_type(private_ike_cert_pre_t *this)
+{
+       return IKE_CERT_PRE;
+}
+
+/**
+ * Implementation of task_t.migrate
+ */
+static void migrate(private_ike_cert_pre_t *this, ike_sa_t *ike_sa)
+{
+       this->ike_sa = ike_sa;
+}
+
+/**
+ * Implementation of task_t.destroy
+ */
+static void destroy(private_ike_cert_pre_t *this)
+{
+       free(this);
+}
+
+/*
+ * Described in header.
+ */
+ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator)
+{
+       private_ike_cert_pre_t *this = malloc_thing(private_ike_cert_pre_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;
+       
+       if (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->ike_sa = ike_sa;
+       this->initiator = initiator;
+       
+       return &this->public;
+}
diff --git a/src/charon/sa/tasks/ike_cert_pre.h b/src/charon/sa/tasks/ike_cert_pre.h
new file mode 100644 (file)
index 0000000..c7422e6
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007-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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup ike_cert_pre ike_cert_pre
+ * @{ @ingroup tasks
+ */
+
+#ifndef IKE_CERT_PRE_H_
+#define IKE_CERT_PRE_H_
+
+typedef struct ike_cert_pre_t ike_cert_pre_t;
+
+#include <library.h>
+#include <sa/ike_sa.h>
+#include <sa/tasks/task.h>
+
+/**
+ * Task of type ike_cert_post, certificate processing before authentication.
+ */
+struct ike_cert_pre_t {
+
+       /**
+        * Implements the task_t interface
+        */
+       task_t task;
+};
+
+/**
+ * Create a new ike_cert_pre task.
+ *
+ * The initiator parameter means the original initiator, not the initiator
+ * of the certificate request.
+ *
+ * @param ike_sa               IKE_SA this task works for
+ * @param initiator            TRUE if thask is the original initator
+ * @return                             ike_cert_pre task to handle by the task_manager
+ */
+ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator);
+
+#endif /* IKE_CERT_PRE_H_ @} */
index 3c73395a50b4adba7e99f49c1fde467bfad9b6ed..2af0aed9618f71eaaca6891df1d196e1a2278bf4 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_config.c
- *
- * @brief Implementation of the ike_config task.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "ike_config.h"
index a7cfddff0f5495e811a8af16f32ff0e066c916e7..9ee2f59be5e06516a9e47421aea57f1c662054c6 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_config.h
- * 
- * @brief Interface ike_config_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_config ike_config
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_CONFIG_H_
@@ -30,13 +30,8 @@ typedef struct ike_config_t ike_config_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type IKE_CONFIG, sets up a virtual IP and other
+ * Task of type IKE_CONFIG, sets up a virtual IP and other
  * configurations for an IKE_SA.
- *
- * @b Constructors:
- *  - ike_config_create()
- * 
- * @ingroup tasks
  */
 struct ike_config_t {
 
@@ -47,7 +42,7 @@ struct ike_config_t {
 };
 
 /**
- * @brief Create a new ike_config task.
+ * Create a new ike_config task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param initiator            TRUE for initiator
@@ -55,4 +50,4 @@ struct ike_config_t {
  */
 ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator);
 
-#endif /* IKE_CONFIG_H_ */
+#endif /* IKE_CONFIG_H_ @} */
index 1a3656ca64f8646812d4f4ea99813caf01947cc0..6e1ee8b10b76fa223e99e5276b28e1cd7b7d72b8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_delete.c
- *
- * @brief Implementation of the ike_delete task.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "ike_delete.h"
index e8ec5ebbe146ee333671b141e43f7ac2337c99db..f9cb4dc646720e45c666118d3030f54e4a5a2235 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_delete.h
- * 
- * @brief Interface ike_delete_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_delete ike_delete
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_DELETE_H_
@@ -30,12 +30,7 @@ typedef struct ike_delete_t ike_delete_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type ike_delete, delete an IKE_SA.
- *
- * @b Constructors:
- *  - ike_delete_create()
- * 
- * @ingroup tasks
+ * Task of type ike_delete, delete an IKE_SA.
  */
 struct ike_delete_t {
 
@@ -46,7 +41,7 @@ struct ike_delete_t {
 };
 
 /**
- * @brief Create a new ike_delete task.
+ * Create a new ike_delete task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param initiator            TRUE if we initiate the delete
@@ -54,4 +49,4 @@ struct ike_delete_t {
  */
 ike_delete_t *ike_delete_create(ike_sa_t *ike_sa, bool initiator);
 
-#endif /* IKE_DELETE_H_ */
+#endif /* IKE_DELETE_H_ @} */
index be751766e92c908629f96ba59c100d9403a60bde..04c5a66d1949b69ef5db3f42f0884c2fea4a3ec7 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_dpd.c
- *
- * @brief Implementation of the ike_dpd task.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "ike_dpd.h"
index 531b0502df5dda4f10c1110eb2dd32f5590454b8..56bbee39941f82bb3ae51d7d459f384860f69a5e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_dpd.h
- * 
- * @brief Interface ike_dpd_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_dpd ike_dpd
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_DPD_H_
@@ -30,14 +30,9 @@ typedef struct ike_dpd_t ike_dpd_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type ike_dpd, detects dead peers.
+ * Task of type ike_dpd, detects dead peers.
  *
  * The DPD task actually does nothing, as a DPD has no associated payloads.
- *
- * @b Constructors:
- *  - ike_dpd_create()
- * 
- * @ingroup tasks
  */
 struct ike_dpd_t {
 
@@ -48,11 +43,11 @@ struct ike_dpd_t {
 };
 
 /**
- * @brief Create a new ike_dpd task.
+ * Create a new ike_dpd task.
  *
  * @param initiator            TRUE if thask is the original initator
  * @return                             ike_dpd task to handle by the task_manager
  */
 ike_dpd_t *ike_dpd_create(bool initiator);
 
-#endif /* IKE_DPD_H_ */
+#endif /* IKE_DPD_H_ @} */
index 42b47a82feaee1600ea2e9e308166fc3e2c28397..6bb3688ea36a42354d5412329c21fed45bf87674 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_init.c
- *
- * @brief Implementation of the ike_init task.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "ike_init.h"
@@ -195,7 +190,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
                                this->dh_group = ke_payload->get_dh_group_number(ke_payload);
                                if (!this->initiator)
                                {
-                                       this->dh = diffie_hellman_create(this->dh_group);
+                                       this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
                                }
                                if (this->dh)
                                {
@@ -241,7 +236,7 @@ static status_t build_i(private_ike_init_t *this, message_t *message)
        if (!this->dh)
        {
                this->dh_group = this->config->get_dh_group(this->config);
-               this->dh = diffie_hellman_create(this->dh_group);
+               this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
                if (this->dh == NULL)
                {
                        SIG(IKE_UP_FAILED, "configured DH group %N not supported",
@@ -532,7 +527,7 @@ static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa)
        
        this->ike_sa = ike_sa;
        this->proposal = NULL;
-       this->dh = diffie_hellman_create(this->dh_group);
+       this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
 }
 
 /**
index f60c096e8a2a568e39ead88067d10d1865aa387d..67afd2b8d71fef9b375306cec6a59dc1ab4a3dea 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_init.h
- * 
- * @brief Interface ike_init_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_init ike_init
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_INIT_H_
@@ -30,14 +30,9 @@ typedef struct ike_init_t ike_init_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type IKE_INIT, creates an IKE_SA without authentication.
+ * Task of type IKE_INIT, creates an IKE_SA without authentication.
  *
  * The authentication of is handle in the ike_auth task.
- *
- * @b Constructors:
- *  - ike_init_create()
- * 
- * @ingroup tasks
  */
 struct ike_init_t {
 
@@ -47,16 +42,15 @@ struct ike_init_t {
        task_t task;
        
        /**
-        * @brief Get the lower of the two nonces, used for rekey collisions.
+        * Get the lower of the two nonces, used for rekey collisions.
         *
-        * @param this          calling object
         * @return                      lower nonce
         */
        chunk_t (*get_lower_nonce) (ike_init_t *this);
 };
 
 /**
- * @brief Create a new IKE_INIT task.
+ * Create a new IKE_INIT task.
  *
  * @param ike_sa               IKE_SA this task works for (new one when rekeying)
  * @param initiator            TRUE if thask is the original initator
@@ -65,4 +59,4 @@ struct ike_init_t {
  */
 ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa);
 
-#endif /* IKE_INIT_H_ */
+#endif /* IKE_INIT_H_ @} */
index a53c243f0afb701cfbd2f9d3db3e833586808780..62a1ad3cdfa578312a588100879535efbf4d8c9b 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_mobike.c
- *
- * @brief Implementation of the ike_mobike task.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "ike_mobike.h"
index bb5150723dc45ca79e92f2bdc84be3e98bdcd583..7325f5a6fd2e107df782815fd3d766ff03069f5b 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_mobike.h
- * 
- * @brief Interface ike_mobike_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_mobike ike_mobike
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_MOBIKE_H_
@@ -31,7 +31,7 @@ typedef struct ike_mobike_t ike_mobike_t;
 #include <network/packet.h>
 
 /**
- * @brief Task of type ike_mobike, detects and handles MOBIKE extension.
+ * Task of type ike_mobike, detects and handles MOBIKE extension.
  *
  * The MOBIKE extension is defined in RFC4555. It allows to update IKE
  * and IPsec tunnel addresses.
@@ -39,11 +39,6 @@ typedef struct ike_mobike_t ike_mobike_t;
  * support, allows the exchange of ADDITIONAL_*_ADDRESS to exchange additional
  * endpoints and handles the UPDATE_SA_ADDRESS notify to finally update 
  * endpoints.
- *
- * @b Constructors:
- *  - ike_mobike_create()
- * 
- * @ingroup tasks
  */
 struct ike_mobike_t {
 
@@ -53,36 +48,33 @@ struct ike_mobike_t {
        task_t task;
        
        /**
-        * @brief Use the task to roam to other addresses.
+        * Use the task to roam to other addresses.
         *
-        * @param this                  calling object
         * @param address               TRUE to include address list update
         */
        void (*roam)(ike_mobike_t *this, bool address);
        
        /**
-        * @brief Transmision hook, called by task manager.
+        * Transmision hook, called by task manager.
         *
         * The task manager calls this hook whenever it transmits a packet. It 
         * allows the mobike task to send the packet on multiple paths to do path
         * probing.
         *
-        * @param this                  calling object
         * @param packet                the packet to transmit
         */
        void (*transmit)(ike_mobike_t *this, packet_t *packet);
        
        /**
-        * @brief Check if this task is probing for routability.
+        * Check if this task is probing for routability.
         *
-        * @param this                  calling object
         * @return                              TRUE if task is probing
         */
        bool (*is_probing)(ike_mobike_t *this); 
 };
 
 /**
- * @brief Create a new ike_mobike task.
+ * Create a new ike_mobike task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param initiator            TRUE if taks is initiated by us
@@ -90,5 +82,4 @@ struct ike_mobike_t {
  */
 ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator);
 
-#endif /* IKE_MOBIKE_H_ */
-
+#endif /* IKE_MOBIKE_H_ @} */
index 4c64ff8baf321ee38383d8d5e78a2622844e5e95..1662a3268b59c4771a58ef39fa978d535a1e188d 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_natd.c
- *
- * @brief Implementation of the ike_natd task.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Martin Willi
  * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "ike_natd.h"
@@ -308,6 +303,12 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
        iterator_t *iterator;
        host_t *host;
        
+       if (this->hasher == NULL)
+       {
+               DBG1(DBG_IKE, "unable to build NATD payloads, SHA1 not supported");
+               return NEED_MORE;
+       }
+       
        /* destination is always set */
        host = message->get_destination(message);
        notify = build_natd_payload(this, NAT_DETECTION_DESTINATION_IP, host);
@@ -368,6 +369,12 @@ static status_t build_r(private_ike_natd_t *this, message_t *message)
 
        if (this->src_seen && this->dst_seen)
        {
+               if (this->hasher == NULL)
+               {
+                       DBG1(DBG_IKE, "unable to build NATD payloads, SHA1 not supported");
+                       return SUCCESS;
+               }
+       
                /* initiator seems to support NAT detection, add response */
                me = message->get_source(message);
                notify = build_natd_payload(this, NAT_DETECTION_SOURCE_IP, me);
@@ -415,7 +422,7 @@ static void migrate(private_ike_natd_t *this, ike_sa_t *ike_sa)
  */
 static void destroy(private_ike_natd_t *this)
 {
-       this->hasher->destroy(this->hasher);
+       DESTROY_IF(this->hasher);
        free(this);
 }
 
@@ -443,7 +450,7 @@ ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator)
        
        this->ike_sa = ike_sa;
        this->initiator = initiator;
-       this->hasher = hasher_create(HASH_SHA1);
+       this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
        this->src_seen = FALSE;
        this->dst_seen = FALSE;
        this->src_matched = FALSE;
index 8d0cb58b4f9e6254c5b11a59c43e7a02e555d9ee..793408797739f2c6f8a0b3047e873cde7952a0ef 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_natd.h
- * 
- * @brief Interface ike_natd_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_natd ike_natd
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_NATD_H_
@@ -30,12 +30,7 @@ typedef struct ike_natd_t ike_natd_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type ike_natd, detects NAT situation in IKE_SA_INIT exchange.
- *
- * @b Constructors:
- *  - ike_natd_create()
- * 
- * @ingroup tasks
+ * Task of type ike_natd, detects NAT situation in IKE_SA_INIT exchange.
  */
 struct ike_natd_t {
 
@@ -46,7 +41,7 @@ struct ike_natd_t {
 };
 
 /**
- * @brief Create a new ike_natd task.
+ * Create a new ike_natd task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param initiator            TRUE if thask is the original initator
@@ -54,4 +49,4 @@ struct ike_natd_t {
  */
 ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator);
 
-#endif /* IKE_NATD_H_ */
+#endif /* IKE_NATD_H_ @} */
index 6f632733ab395c79e6c1b07f1ce00aab713bcfd3..ce3a3fd00a33dc7913ae81f672cacb0772d6891d 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_p2p.c
- *
- * @brief Implementation of the ike_p2p task.
- *
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 "ike_p2p.h"
 
 #include <string.h>
index 327ac49d8aded2d8b1c17b9431941a37b733d41f..fe6bbd1a287462eaf2f6d13587c04ac5f693c38c 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_p2p.h
- * 
- * @brief Interface ike_p2p_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_p2p ike_p2p
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_P2P_H_
@@ -30,7 +30,7 @@ typedef struct ike_p2p_t ike_p2p_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type IKE_P2P, detects and handles P2P-NAT-T extensions.
+ * Task of type IKE_P2P, detects and handles P2P-NAT-T extensions.
  *
  * This tasks handles the P2P_MEDIATION notify exchange to setup a mediation
  * connection, allows to initiate mediated connections using P2P_CONNECT
@@ -40,11 +40,6 @@ typedef struct ike_p2p_t ike_p2p_t;
  * @note This task has to be activated before the IKE_AUTH task, because that
  * task generates the IKE_SA_INIT message so that no more payloads can be added
  * to it afterwards.
- *
- * @b Constructors:
- *  - ike_p2p_create()
- * 
- * @ingroup tasks
  */
 struct ike_p2p_t {
 
@@ -54,38 +49,34 @@ struct ike_p2p_t {
        task_t task;
        
        /**
-        * @brief Initiates a connection with another peer (i.e. sends a P2P_CONNECT
+        * Initiates a connection with another peer (i.e. sends a P2P_CONNECT
         * to the mediation server)
         *
-        * @param this                          object
         * @param peer_id                       ID of the other peer (gets cloned)
         */
        void (*connect)(ike_p2p_t *this, identification_t *peer_id);
        
        /**
-        * @brief Responds to a P2P_CONNECT from another peer (i.e. sends a P2P_CONNECT
+        * Responds to a P2P_CONNECT from another peer (i.e. sends a P2P_CONNECT
         * to the mediation server)
         * 
-        * @param this                          object
         * @param peer_id                       ID of the other peer (gets cloned)
         * @param session_id            the session ID as provided by the initiator (gets cloned)
         */
        void (*respond)(ike_p2p_t *this, identification_t *peer_id, chunk_t session_id);
        
        /**
-        * @brief Sends a P2P_CALLBACK to a peer that previously requested another peer.
+        * Sends a P2P_CALLBACK to a peer that previously requested another peer.
         * 
-        * @param this                          object
         * @param peer_id                       ID of the other peer (gets cloned)
         */
        void (*callback)(ike_p2p_t *this, identification_t *peer_id);
        
        /**
-        * @brief Relays data to another peer (i.e. sends a P2P_CONNECT to the peer)
+        * Relays data to another peer (i.e. sends a P2P_CONNECT to the peer)
         * 
         * Data gets cloned.
         * 
-        * @param this                          object
         * @param requester                     ID of the requesting peer
         * @param session_id            content of the P2P_SESSIONID notify
         * @param session_key           content of the P2P_SESSIONKEY notify
@@ -98,7 +89,7 @@ struct ike_p2p_t {
 };
 
 /**
- * @brief Create a new ike_p2p task.
+ * Create a new ike_p2p task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param initiator            TRUE if taks is initiated by us
@@ -106,5 +97,4 @@ struct ike_p2p_t {
  */
 ike_p2p_t *ike_p2p_create(ike_sa_t *ike_sa, bool initiator);
 
-
-#endif /*IKE_P2P_H_*/
+#endif /*IKE_P2P_H_ @} */
index 0e98382a8c4227ecd20d221bd2116b72d60cb32a..7b69a938fea676345fa2d3e3566526abf9ccf88d 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_reauth.c
- *
- * @brief Implementation of the ike_reauth task.
- *
- */
-
 /*
  * Copyright (C) 2006-2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "ike_reauth.h"
index 3c872e1e1c48bba771d623f2e9f5ae1b9053c90c..f5599fd76351f365322689cc0808b0e28481181f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_reauth.h
- * 
- * @brief Interface ike_reauth_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_reauth ike_reauth
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_REAUTH_H_
@@ -30,12 +30,7 @@ typedef struct ike_reauth_t ike_reauth_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type ike_reauth, reestablishes an IKE_SA.
- *
- * @b Constructors:
- *  - ike_reauth_create()
- * 
- * @ingroup tasks
+ * Task of type ike_reauth, reestablishes an IKE_SA.
  */
 struct ike_reauth_t {
 
@@ -46,7 +41,7 @@ struct ike_reauth_t {
 };
 
 /**
- * @brief Create a new ike_reauth task.
+ * Create a new ike_reauth task.
  *
  * This task is initiator only.
  *
@@ -55,5 +50,4 @@ struct ike_reauth_t {
  */
 ike_reauth_t *ike_reauth_create(ike_sa_t *ike_sa);
 
-#endif /* IKE_REAUTH_H_ */
-
+#endif /* IKE_REAUTH_H_ @} */
index 827f951560cdea6d4e8318790c4321064fca92e2..1428d569921224628f7835e7b976c945dc435efc 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_rekey.c
- *
- * @brief Implementation of the ike_rekey task.
- *
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "ike_rekey.h"
index 125422efdaaa60fe801f21f855664521e732a847..06889cb39078db1bee324b9f9e42aedd0930f238 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ike_rekey.h
- * 
- * @brief Interface ike_rekey_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ike_rekey ike_rekey
+ * @{ @ingroup tasks
  */
 
 #ifndef IKE_REKEY_H_
@@ -30,12 +30,7 @@ typedef struct ike_rekey_t ike_rekey_t;
 #include <sa/tasks/task.h>
 
 /**
- * @brief Task of type IKE_REKEY, rekey an established IKE_SA.
- *
- * @b Constructors:
- *  - ike_rekey_create()
- * 
- * @ingroup tasks
+ * Task of type IKE_REKEY, rekey an established IKE_SA.
  */
 struct ike_rekey_t {
 
@@ -45,20 +40,19 @@ struct ike_rekey_t {
        task_t task;
        
        /**
-        * @brief Register a rekeying task which collides with this one.
+        * Register a rekeying task which collides with this one.
         *
         * If two peers initiate rekeying at the same time, the collision must
         * be handled gracefully. The task manager is aware of what exchanges
         * are going on and notifies the outgoing task by passing the incoming.
         *
-        * @param this          task initated by us
         * @param other         incoming task
         */
        void (*collide)(ike_rekey_t* this, task_t *other);
 };
 
 /**
- * @brief Create a new IKE_REKEY task.
+ * Create a new IKE_REKEY task.
  *
  * @param ike_sa               IKE_SA this task works for
  * @param initiator            TRUE for initiator, FALSE for responder
@@ -66,4 +60,4 @@ struct ike_rekey_t {
  */
 ike_rekey_t *ike_rekey_create(ike_sa_t *ike_sa, bool initiator);
 
-#endif /* IKE_REKEY_H_ */
+#endif /* IKE_REKEY_H_ @} */
index cc20a88616858df6835b9bb0dcfd955fa5301627..0ff2afd77cfdb5bee68b257dce8373a315cd3a4d 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file task.c
- * 
- * @brief Enum values for task types
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2007 Martin Willi
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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 "task.h"
@@ -29,7 +24,8 @@ ENUM(task_type_names, IKE_INIT, CHILD_REKEY,
        "IKE_MOBIKE",
        "IKE_AUTHENTICATE",
        "IKE_AUTH_LIFETIME",
-       "IKE_CERT",
+       "IKE_CERT_PRE",
+       "IKE_CERT_POST",
        "IKE_CONFIG",
        "IKE_REKEY",
        "IKE_REAUTH",
index a59207711adacdad5085ddfe55dcbcbad24a2822..773bc60c63d701d672c90cc570c7b7bd78fcd3df 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file task.h
- * 
- * @brief Interface task_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2006 Martin Willi
  * WITHOUT ANY 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 task task
+ * @{ @ingroup tasks
  */
 
 #ifndef TASK_H_
@@ -32,9 +32,7 @@ typedef struct task_t task_t;
 #include <encoding/message.h>
 
 /**
- * @brief Different kinds of tasks.
- * 
- * @ingroup tasks
+ * Different kinds of tasks.
  */
 enum task_type_t {
        /** establish an unauthenticated IKE_SA */
@@ -47,8 +45,10 @@ enum task_type_t {
        IKE_AUTHENTICATE,
        /** AUTH_LIFETIME negotiation, RFC4478 */
        IKE_AUTH_LIFETIME,
-       /** exchange certificates and requests */
-       IKE_CERT,
+       /** certificate processing before authentication (certreqs, cert parsing) */
+       IKE_CERT_PRE,
+       /** certificate processing after authentication (certs payload generation) */
+       IKE_CERT_POST,
        /** Configuration payloads, virtual IP and such */
        IKE_CONFIG,
        /** rekey an IKE_SA */
@@ -77,7 +77,7 @@ enum task_type_t {
 extern enum_name_t *task_type_names;
 
 /**
- * @brief Interface for a task, an operation handled within exchanges.
+ * Interface for a task, an operation handled within exchanges.
  *
  * A task is an elemantary operation. It may be handled by a single or by
  * multiple exchanges. An exchange may even complete multiple tasks.
@@ -94,18 +94,12 @@ extern enum_name_t *task_type_names;
  * the task needs further build()/process() calls to complete, the manager
  * leaves the taks in the queue. A returned FAILED indicates a critical failure.
  * The manager closes the IKE_SA whenever a task returns FAILED.
- *
- * @b Constructors:
- *  - None, use implementations specific constructors
- * 
- * @ingroup tasks
  */
 struct task_t {
 
        /**
-        * @brief Build a request or response message for this task.
+        * Build a request or response message for this task.
         * 
-        * @param this                  calling object
         * @param message               message to add payloads to
         * @return
         *                                              - FAILED if a critical error occured
@@ -115,9 +109,8 @@ struct task_t {
        status_t (*build) (task_t *this, message_t *message);
 
        /**
-        * @brief Process a request or response message for this task.
+        * Process a request or response message for this task.
         * 
-        * @param this                  calling object
         * @param message               message to read payloads from
         * @return
         *                                              - FAILED if a critical error occured
@@ -127,14 +120,12 @@ struct task_t {
        status_t (*process) (task_t *this, message_t *message);
 
        /**
-        * @brief Get the type of the task implementation.
-        * 
-        * @param this                  calling object
+        * Get the type of the task implementation.
         */
        task_type_t (*get_type) (task_t *this);
        
        /**
-        * @brief Migrate a task to a new IKE_SA.
+        * Migrate a task to a new IKE_SA.
         *
         * After migrating a task, it goes back to a state where it can be
         * used again to initate an exchange. This is useful when a task
@@ -144,17 +135,14 @@ struct task_t {
         * try.
         * The ike_sa is the new IKE_SA this task belongs to and operates on.
         *
-        * @param this                  calling object
         * @param ike_sa                new IKE_SA this task works for
         */
        void (*migrate) (task_t *this, ike_sa_t *ike_sa);
        
        /**
-        * @brief Destroys a task_t object.
-        *
-        * @param this                  calling object
+        * Destroys a task_t object.
         */
        void (*destroy) (task_t *this);
 };
 
-#endif /* TASK_H_ */
+#endif /* TASK_H_ @} */
diff --git a/src/libfast/Makefile.am b/src/libfast/Makefile.am
new file mode 100644 (file)
index 0000000..6104f33
--- /dev/null
@@ -0,0 +1,8 @@
+lib_LTLIBRARIES = libfast.la
+
+libfast_la_SOURCES = context.h dispatcher.c request.h session.h \
+  controller.h dispatcher.h request.c session.c filter.h
+libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
+  -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl -lz
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I/usr/include/ClearSilver
+AM_CFLAGS = -rdynamic
similarity index 78%
rename from src/manager/lib/context.h
rename to src/libfast/context.h
index 23c979b8e9dd1ed801f05430828a8344a7b63784..6b9e83310e5a96775b11f7a6adf0d94100904373 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file context.h
- * 
- * @brief Interface of context_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 context context
+ * @{ @ingroup libfast
  */
 
 #ifndef CONTEXT_H_
 typedef struct context_t context_t;
 
 /**
- * @brief Constructor function for a context
+ * Constructor function for a user specific context.
  */
 typedef context_t *(*context_constructor_t)(void *param);
 
 /**
- * @brief Custom session context
- *
+ * User specific session context, to extend.
  */
 struct context_t {
        
        /**
-        * @brief Destroy the context_t.
-        *
-        * @param this                  calling object
+        * Destroy the context_t.
         */
        void (*destroy) (context_t *this);
 };
 
-#endif /* CONTEXT_H_ */
+#endif /* CONTEXT_H_ @}*/
similarity index 67%
rename from src/manager/lib/controller.h
rename to src/libfast/controller.h
index 5b39f559c45e706cda7c9a7e74e5e862f9b3804a..9ac641fefb3be469894d05a11beaec4ba851bfd1 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file controller.h
- * 
- * @brief Interface controller_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 controller_i controller
+ * @{ @ingroup libfast
  */
 
 #ifndef CONTROLLER_H_
 typedef struct controller_t controller_t;
 
 /**
- * @brief Controller action handle function
- *
- * @param request              http request
- * @param response             http response
- */
-typedef void *(*controller_handler_t)(controller_t *this, request_t *request);
-
-/**
- * @brief Constructor function for a controller
+ * Constructor function for a controller.
  *
- * @param context              session specific context
- * @param param                        user supplied param
+ * @param context              session specific context, implements context_t
+ * @param param                        user supplied param, as registered to the dispatcher
  */
 typedef controller_t *(*controller_constructor_t)(context_t* context, void *param);
 
 /**
- * @brief Controller interface, to be implemented by users controllers.
+ * Controller interface, to be implemented by users controllers.
  *
+ * Controller instances get created per session, so each session has an
+ * associated set of private controller instances.
+ * The controller handle function is called for each incoming request.
  */
 struct controller_t {
        
        /**
-        * @brief Get the name of the controller.
+        * Get the name of the controller.
         *
         * @return                              name of the controller
         */
        char* (*get_name)(controller_t *this);
        
        /**
-        * @brief Handle a HTTP request for that controller.
+        * Handle a HTTP request for that controller.
         *
         * Request URLs are parsed in the form
         * controller_name/p1/p2/p3/p4/p5 with a maximum of 5 parameters. Each
@@ -73,12 +68,12 @@ struct controller_t {
         * @return
         */
        void (*handle)(controller_t *this, request_t *request,
-                                  char *a1, char *a2, char *a3, char *a4, char *a5);
+                                  char *p1, char *p2, char *p3, char *p4, char *p5);
                
        /**
-        * @brief Destroy the controller instance.
+        * Destroy the controller instance.
         */
        void (*destroy) (controller_t *this);
 };
 
-#endif /* CONTROLLER_H_ */
+#endif /* CONTROLLER_H_ @} */
similarity index 58%
rename from src/manager/lib/dispatcher.c
rename to src/libfast/dispatcher.c
index ce53d39ea1760e2e5ee32e2220c127db41f3cc6b..d5708d0ac5703d5899490c135290c0e32ce853c8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file dispatcher.c
- *
- * @brief Implementation of dispatcher_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "dispatcher.h"
@@ -76,39 +71,29 @@ struct private_dispatcher_t {
        time_t timeout;
        
        /**
-        * List of controllers controller_constructor_t
+        * running in debug mode?
         */
-       linked_list_t *controllers;
-       
-       /** 
-        * constructor function to create session context (in constructor_entry_t)
-        */
-       context_constructor_t context_constructor;
+       bool debug;
        
        /**
-        * user param to context constructor
-        */
-       void *param;
-       
-       /**
-        * thread specific initialization handler
+        * List of controllers controller_constructor_t
         */
-       void (*init)(void *param);
+       linked_list_t *controllers;
        
        /**
-        * argument to pass to thread intiializer
+        * List of filters filter_constructor_t
         */
-       void *init_param;
+       linked_list_t *filters;
        
-       /**
-        * thread specific deinitialization handler
+       /** 
+        * constructor function to create session context (in controller_entry_t)
         */
-       void (*deinit)(void *param);
+       context_constructor_t context_constructor;
        
        /**
-        * param tho thread specific deinitialization handler
+        * user param to context constructor
         */
-       void *deinit_param;
+       void *param;
 };
 
 typedef struct {
@@ -116,17 +101,28 @@ typedef struct {
        controller_constructor_t constructor;
        /** parameter to constructor */
        void *param;
-} constructor_entry_t;
+} controller_entry_t;
+
+typedef struct {
+       /** constructor function */
+       filter_constructor_t constructor;
+       /** parameter to constructor */
+       void *param;
+} filter_entry_t;
 
 typedef struct {
        /** session instance */
        session_t *session;
        /** condvar to wait for session */
        pthread_cond_t cond;
+       /** client host address, to prevent session hijacking */
+       char *host;
        /** TRUE if session is in use */
        bool in_use;
        /** last use of the session */
        time_t used;
+       /** has the session been closed by the handler? */
+       bool closed;
 } session_entry_t;
 
 /**
@@ -135,10 +131,12 @@ typedef struct {
 static session_t* load_session(private_dispatcher_t *this)
 {
        iterator_t *iterator;
-       constructor_entry_t *entry;
+       controller_entry_t *centry;
+       filter_entry_t *fentry;
        session_t *session;
        context_t *context = NULL;
        controller_t *controller;
+       filter_t *filter;
        
        if (this->context_constructor)
        {
@@ -147,28 +145,39 @@ static session_t* load_session(private_dispatcher_t *this)
        session = session_create(context);
        
        iterator = this->controllers->create_iterator(this->controllers, TRUE);
-       while (iterator->iterate(iterator, (void**)&entry))
+       while (iterator->iterate(iterator, (void**)&centry))
        {
-               controller = entry->constructor(context, entry->param);
+               controller = centry->constructor(context, centry->param);
                session->add_controller(session, controller);
        }
        iterator->destroy(iterator);
        
+       iterator = this->filters->create_iterator(this->filters, TRUE);
+       while (iterator->iterate(iterator, (void**)&fentry))
+       {
+               filter = fentry->constructor(context, fentry->param);
+               session->add_filter(session, filter);
+       }
+       iterator->destroy(iterator);
+       
        return session;
 }
 
 /**
  * create a new session entry
  */
-static session_entry_t *session_entry_create(private_dispatcher_t *this)
+static session_entry_t *session_entry_create(private_dispatcher_t *this,
+                                                                                        char *host)
 {
        session_entry_t *entry;
        
        entry = malloc_thing(session_entry_t);
        entry->in_use = FALSE;
+       entry->closed = FALSE;
        pthread_cond_init(&entry->cond, NULL);
        entry->session = load_session(this);
        entry->used = time(NULL);
+       entry->host = strdup(host);
        
        return entry;
 }
@@ -176,6 +185,7 @@ static session_entry_t *session_entry_create(private_dispatcher_t *this)
 static void session_entry_destroy(session_entry_t *entry)
 {
        entry->session->destroy(entry->session);
+       free(entry->host);
        free(entry);
 }
 
@@ -185,151 +195,119 @@ static void session_entry_destroy(session_entry_t *entry)
 static void add_controller(private_dispatcher_t *this,
                                                   controller_constructor_t constructor, void *param)
 {
-       constructor_entry_t *entry = malloc_thing(constructor_entry_t);
+       controller_entry_t *entry = malloc_thing(controller_entry_t);
        
        entry->constructor = constructor;
        entry->param = param;
        this->controllers->insert_last(this->controllers, entry);
 }
 
+/**
+ * Implementation of dispatcher_t.add_filter.
+ */
+static void add_filter(private_dispatcher_t *this,
+                                          filter_constructor_t constructor, void *param)
+{
+       filter_entry_t *entry = malloc_thing(filter_entry_t);
+       
+       entry->constructor = constructor;
+       entry->param = param;
+       this->filters->insert_last(this->filters, entry);
+}
+
 /**
  * Actual dispatching code 
  */
 static void dispatch(private_dispatcher_t *this)
 {
-       FCGX_Request fcgi_req;
-       
-       if (FCGX_InitRequest(&fcgi_req, this->fd, 0) == 0)
+       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+       while (TRUE)
        {
-               while (TRUE)
+               request_t *request;
+               session_entry_t *current, *found = NULL;
+               iterator_t *iterator;
+               time_t now;
+               char *sid;
+               
+               pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+               request = request_create(this->fd, this->debug);
+               pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+               if (request == NULL)
                {
-                       request_t *request;
-                       session_entry_t *current, *found = NULL;
-                       iterator_t *iterator;
-                       time_t now;
-                       char *sid;
-                       int accepted;
-                       
-                       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
-                       accepted = FCGX_Accept_r(&fcgi_req);
-                       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
-                       
-                       if (accepted != 0)
-                       {
-                               break;
-                       }
-                       
-                       /* prepare */
-                       request = request_create(&fcgi_req, TRUE);
-                       if (request == NULL)
+                       continue;
+               }
+               sid = request->get_cookie(request, "SID");
+               now = time(NULL);
+               
+               /* find session */
+               pthread_mutex_lock(&this->mutex);
+               iterator = this->sessions->create_iterator(this->sessions, TRUE);
+               while (iterator->iterate(iterator, (void**)&current))
+               {
+                       /* check all sessions for timeout or close flag 
+                        * TODO: use a seperate cleanup thread */
+                       if (!current->in_use &&
+                               (current->used < now - this->timeout || current->closed))
                        {
+                               iterator->remove(iterator);
+                               session_entry_destroy(current);
                                continue;
                        }
-                       sid = request->get_cookie(request, "SID");
-                       now = time(NULL);
-                       
-                       /* find session */
-                       pthread_mutex_lock(&this->mutex);
-                       iterator = this->sessions->create_iterator(this->sessions, TRUE);
-                       while (iterator->iterate(iterator, (void**)&current))
+                       /* find by session ID. Prevent session hijacking by host check */
+                       if (!found && sid &&
+                               streq(current->session->get_sid(current->session), sid) &&
+                               streq(current->host, request->get_host(request)))
                        {
-                               /* check all sessions for timeout */
-                               if (!current->in_use &&
-                                       current->used < now - this->timeout)
-                               {
-                                       iterator->remove(iterator);
-                                       session_entry_destroy(current);
-                                       continue;
-                               }
-                               if (!found && sid &&
-                                       streq(current->session->get_sid(current->session), sid))
-                               {
-                                       found = current;
-                               }
+                               found = current;
                        }
-                       iterator->destroy(iterator);
-                       
-                       if (found)
-                       {       /* wait until session is unused */
-                               while (found->in_use)
-                               {
-                                       pthread_cond_wait(&found->cond, &this->mutex);
-                               }
-                       }
-                       else
-                       {       /* create a new session if not found */
-                               found = session_entry_create(this);
-                               this->sessions->insert_first(this->sessions, found);
-                       }
-                       found->in_use = TRUE;
-                       pthread_mutex_unlock(&this->mutex);
+               }
+               iterator->destroy(iterator);
                
-                       /* start processing */
-                       found->session->process(found->session, request);
-                       found->used = time(NULL);
-                       
-                       /* release session */
-                       pthread_mutex_lock(&this->mutex);
-                       found->in_use = FALSE;
-                       pthread_cond_signal(&found->cond);
-                       pthread_mutex_unlock(&this->mutex);
-                       
-                       /* cleanup */
-                       request->destroy(request);
-                       
-                       /*
-                   FCGX_FPrintF(fcgi_req.out, "<ul>");
-                   char **env = fcgi_req.envp;
-                   while (*env)
-                   {
-                       FCGX_FPrintF(fcgi_req.out, "<li>%s</li>", *env);
-                       env++;
-                   }
-                   FCGX_FPrintF(fcgi_req.out, "</ul>");
-                   */
+               if (found)
+               {
+                       /* wait until session is unused */
+                       while (found->in_use)
+                       {
+                               pthread_cond_wait(&found->cond, &this->mutex);
+                       }
                }
-       }
-}
-
-/**
- * Setup thread and start dispatching 
- */
-static void start_dispatching(private_dispatcher_t *this)
-{
-       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
-       if (this->init)
-       {
-               this->init(this->init_param);
-       }
-       if (this->deinit)
-       {
-               pthread_cleanup_push(this->deinit, this->deinit_param);
-               dispatch(this);
-               pthread_cleanup_pop(1);
-       }
-       else
-       {
-               dispatch(this);
+               else
+               {       /* create a new session if not found */
+                       found = session_entry_create(this, request->get_host(request));
+                       this->sessions->insert_first(this->sessions, found);
+               }
+               found->in_use = TRUE;
+               pthread_mutex_unlock(&this->mutex);
+       
+               /* start processing */
+               found->session->process(found->session, request);
+               found->used = time(NULL);
+               
+               /* release session */
+               pthread_mutex_lock(&this->mutex);
+               found->in_use = FALSE;
+               found->closed = request->session_closed(request);
+               pthread_cond_signal(&found->cond);
+               pthread_mutex_unlock(&this->mutex);
+               
+               /* cleanup */
+               request->destroy(request);
        }
 }
 
 /**
  * Implementation of dispatcher_t.run.
  */
-static void run(private_dispatcher_t *this, int threads,
-                               void(*init)(void *param), void *init_param,
-                               void(*deinit)(void *param), void *deinit_param)
+static void run(private_dispatcher_t *this, int threads)
 {
-       this->init = init;
-       this->init_param = init_param;
-       this->deinit = deinit;
-       this->deinit_param = deinit_param;
        this->thread_count = threads;
        this->threads = malloc(sizeof(pthread_t) * threads);
        while (threads)
        {
                if (pthread_create(&this->threads[threads - 1],
-                                                  NULL, (void*)start_dispatching, this) == 0)
+                                                  NULL, (void*)dispatch, this) == 0)
                {
                        threads--;
                }
@@ -365,29 +343,33 @@ static void destroy(private_dispatcher_t *this)
        }
        this->sessions->destroy_function(this->sessions, (void*)session_entry_destroy);
        this->controllers->destroy_function(this->controllers, free);
+       this->filters->destroy_function(this->filters, free);
        free(this);
 }
 
 /*
  * see header file
  */
-dispatcher_t *dispatcher_create(char *socket, int timeout,
+dispatcher_t *dispatcher_create(char *socket, bool debug, int timeout,
                                                                context_constructor_t constructor, void *param)
 {
        private_dispatcher_t *this = malloc_thing(private_dispatcher_t);
 
        this->public.add_controller = (void(*)(dispatcher_t*, controller_constructor_t, void*))add_controller;
-       this->public.run = (void(*)(dispatcher_t*, int threads,void(*)(void *),void *,void(*)(void *),void *))run;
+       this->public.add_filter = (void(*)(dispatcher_t*,filter_constructor_t constructor, void *param))add_filter;
+       this->public.run = (void(*)(dispatcher_t*, int threads))run;
        this->public.waitsignal = (void(*)(dispatcher_t*))waitsignal;
        this->public.destroy = (void(*)(dispatcher_t*))destroy;
        
        this->sessions = linked_list_create();
        this->controllers = linked_list_create();
+       this->filters = linked_list_create();
        this->context_constructor = constructor;
        pthread_mutex_init(&this->mutex, NULL);
        this->param = param;
     this->fd = 0;
     this->timeout = timeout;
+    this->debug = debug;
        
     FCGX_Init();
     
diff --git a/src/libfast/dispatcher.h b/src/libfast/dispatcher.h
new file mode 100644 (file)
index 0000000..b792fb6
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * 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$
+ */
+
+/**
+ * @defgroup libfast libfast
+ * @{
+ * FastCGI Application Server w/ templates.
+ *
+ * Libfast is a framework to write web applications in an MVC fashion. It uses
+ * the ClearSilver template engine and communicates through FastCGI with
+ * the webserver. It is multithreaded and really fast.
+ *
+ * The application has a global context and a session context. The global
+ * context is accessed from all sessions simultaneously and therefore 
+ * needs to be threadsave. Often a database wrapper is the global context.
+ * The session context is instanciated per session. Sessions are managed
+ * automatically through session cookies. The session context is kept alive
+ * until the session times out. It must implement the context_t interface and
+ * a #context_constructor_t is needed to create instances. To each session, 
+ * a set of controllers gets instanciated. The controller instances are per 
+ * session, so you can hold private data for each user.
+ * Controllers need to implement the controller_t interface and need a 
+ * #controller_constructor_t function to create instances.
+ *
+ * A small example shows how to set up libfast:
+ * @code
+       dispatcher_t *dispatcher;
+       your_global_context_implementation_t *global;
+       global = initialize_your_global_context();
+       dispatcher = dispatcher_create(NULL, FALSE, 180,
+                       (context_constructor_t)your_session_context_create, global);
+       dispatcher->add_controller(dispatcher, your_controller1_create, param1);
+       dispatcher->add_controller(dispatcher, your_controller2_create, param2);
+       
+       dispatcher->run(dispatcher, 20);
+       
+       dispatcher->waitsignal(dispatcher);
+       
+       dispatcher->destroy(dispatcher);
+       global->destroy();
+   @endcode
+ * @}
+ *
+ * @defgroup dispatcher dispatcher
+ * @{ @ingroup libfast
+ */
+
+#ifndef DISPATCHER_H_
+#define DISPATCHER_H_
+
+#include "controller.h"
+#include "filter.h"
+
+typedef struct dispatcher_t dispatcher_t;
+
+/**
+ * Dispatcher, accepts connections using multiple threads.
+ *
+ * The dispatcher creates a session for each client (using SID cookies). In
+ * each session, a session context is created using the context constructor.
+ * Each controller is instanciated in the session using the controller
+ * constructor added with add_controller.
+ */
+struct dispatcher_t {
+       
+       /**
+        * Register a controller to the dispatcher.
+        *
+        * The first controller added serves as default controller. Client's
+        * get redirected to it if no other controller matches.
+        *
+        * @param constructor   constructor function to the conntroller
+        * @param param                 param to pass to constructor
+        */
+       void (*add_controller)(dispatcher_t *this,
+                                                  controller_constructor_t constructor, void *param);
+
+       /**
+        * @brief Add a filter to the dispatcher.
+        *
+        * @param constructor   constructor to create filter in session
+        * @param param                 param to pass to constructor
+        */
+       void (*add_filter)(dispatcher_t *this,
+                                          filter_constructor_t constructor, void *param);      
+       
+       /**
+        * Start with dispatching.
+        *
+        * Instanciate a constant thread pool and start dispatching requests.
+        *
+        * @param threads               number of dispatching threads
+        */
+       void (*run)(dispatcher_t *this, int threads);
+       
+       /**
+        * Wait for a relevant signal action.
+        *
+        */
+       void (*waitsignal)(dispatcher_t *this);
+       
+       /**
+        * Destroy the dispatcher_t.
+        */
+       void (*destroy) (dispatcher_t *this);
+};
+
+/**
+ * Create a dispatcher.
+ *
+ * The context constructor is invoked to create a session context for
+ * each session.
+ *
+ * @param socket               FastCGI socket path, NULL for dynamic
+ * @param debug                        no stripping, no compression, timing information
+ * @param timeout              session timeout
+ * @param constructor  construction function for session context
+ * @param param                        parameter to supply to context constructor
+ */
+dispatcher_t *dispatcher_create(char *socket, bool debug, int timeout,
+                                                               context_constructor_t constructor, void *param);
+
+#endif /* DISPATCHER_H_ @} */
diff --git a/src/libfast/filter.h b/src/libfast/filter.h
new file mode 100644 (file)
index 0000000..d2fb8dd
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/*
+ * @defgroup filter filter
+ * @{ @ingroup libfast
+ */
+
+#ifndef FILTER_H_
+#define FILTER_H_
+
+#include "request.h"
+#include "context.h"
+#include "controller.h"
+
+typedef struct filter_t filter_t;
+
+/**
+ * Constructor function for a filter
+ *
+ * @param context              session specific context
+ * @param param                        user supplied param
+ */
+typedef filter_t *(*filter_constructor_t)(context_t* context, void *param);
+
+/**
+ * Filter interface, to be implemented by users filters.
+ */
+struct filter_t {
+       
+       /**
+        * Called before the controller handles the request
+        *
+        * @param request               HTTP request
+        * @param controller    selected controller, before execution
+        * @return                              TRUE to continue request handling
+        */
+       bool (*run)(filter_t *this, request_t *request, controller_t *controller);
+       
+       /**
+        * Destroy the filter instance.
+        */
+       void (*destroy) (filter_t *this);
+};
+
+#endif /* FILTER_H_ @} */
similarity index 58%
rename from src/manager/lib/request.c
rename to src/libfast/request.c
index bbaec10cc690e69a340f248115fd00ffa9b6dced..ef9f661221258d4e7c14ca3fe0747abec8ac4f35 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file request.c
- *
- * @brief Implementation of request_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 +20,7 @@
 #include "request.h"
 
 #include <library.h>
+#include <debug.h>
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
@@ -45,7 +41,12 @@ struct private_request_t {
        /**
         * FastCGI request object
         */
-       FCGX_Request *req;
+       FCGX_Request req;
+       
+       /**
+        * length of the req.envp array
+        */
+       int req_env_len;
        
        /**
         * ClearSilver CGI Kit context
@@ -56,19 +57,24 @@ struct private_request_t {
         * ClearSilver HDF dataset for this request
         */
        HDF *hdf;
+       
+       /** 
+        * close the session?
+        */
+       bool closed;
+       
+       /**
+        * reference count
+        */
+       refcount_t ref;
 };
 
 /**
- * key to a thread specific FCGX_Request, used for ClearSilver cgiwrap callbacks.
+ * key to a the threads "this" request, used for ClearSilver cgiwrap callbacks.
  * ClearSilver cgiwrap is not threadsave, so we use a private
  * context for each thread.
  */
-static pthread_key_t req_key;
-
-/**
- * length of param list in req->envp
- */
-static pthread_key_t req_env_len_key;
+static pthread_key_t this_key;
 
 /**
  * control variable for pthread_once
@@ -80,8 +86,9 @@ pthread_once_t once = PTHREAD_ONCE_INIT;
  */
 static int read_cb(void *null, char *buf, int size)
 {
-       FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
-       return FCGX_GetStr(buf, size, req->in);
+       private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+       
+       return FCGX_GetStr(buf, size, this->req.in);
 }
 
 /**
@@ -89,8 +96,9 @@ static int read_cb(void *null, char *buf, int size)
  */
 static int writef_cb(void *null, const char *format, va_list args)
 {
-       FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
-       FCGX_VFPrintF(req->out, format, args);
+       private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+       
+       FCGX_VFPrintF(this->req.out, format, args);
        return 0;
 }
 /**
@@ -98,8 +106,9 @@ static int writef_cb(void *null, const char *format, va_list args)
  */
 static int write_cb(void *null, const char *buf, int size)
 {
-       FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
-       return FCGX_PutStr(buf, size, req->out);
+       private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+       
+       return FCGX_PutStr(buf, size, this->req.out);
 }
 
 /**
@@ -108,8 +117,9 @@ static int write_cb(void *null, const char *buf, int size)
 static char *getenv_cb(void *null, const char *key)
 {
        char *value;
-       FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
-       value = FCGX_GetParam(key, req->envp);
+       private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+       
+       value = FCGX_GetParam(key, this->req.envp);
        return value ? strdup(value) : NULL;
 }
 
@@ -129,16 +139,15 @@ static int iterenv_cb(void *null, int num, char **key, char **value)
 {
        *key = NULL;
        *value = NULL;
-       FCGX_Request *req = (FCGX_Request*)pthread_getspecific(req_key);
-       int req_env_len = (int)pthread_getspecific(req_env_len_key);
-       if (num < req_env_len)
+       private_request_t *this = (private_request_t*)pthread_getspecific(this_key);
+       if (num < this->req_env_len)
        {
                char *eq;
 
-               eq = strchr(req->envp[num], '=');
+               eq = strchr(this->req.envp[num], '=');
                if (eq)
                {
-                       *key = strndup(req->envp[num], eq - req->envp[num]);
+                       *key = strndup(this->req.envp[num], eq - this->req.envp[num]);
                        *value = strdup(eq + 1);
                }
                if (*key == NULL || *value == NULL)
@@ -164,10 +173,28 @@ static char* get_cookie(private_request_t *this, char *name)
  */
 static char* get_path(private_request_t *this)
 {
-       char * path = FCGX_GetParam("PATH_INFO", this->req->envp);
+       char * path = FCGX_GetParam("PATH_INFO", this->req.envp);
        return path ? path : "";
 }
 
+/**
+ * Implementation of request_t.get_host.
+ */
+static char* get_host(private_request_t *this)
+{
+       char *addr = FCGX_GetParam("REMOTE_ADDR", this->req.envp);
+       return addr ? addr : "";
+}
+
+/**
+ * Implementation of request_t.get_user_agent.
+ */
+static char* get_user_agent(private_request_t *this)
+{
+       char *agent = FCGX_GetParam("HTTP_USER_AGENT", this->req.envp);
+       return agent ? agent : "";
+}
+
 /**
  * Implementation of request_t.get_post_data.
  */
@@ -181,8 +208,9 @@ static char* get_query_data(private_request_t *this, char *name)
  */
 static void add_cookie(private_request_t *this, char *name, char *value)
 {
+       pthread_setspecific(this_key, this);
        cgi_cookie_set (this->cgi, name, value,
-                                       FCGX_GetParam("SCRIPT_NAME", this->req->envp),
+                                       FCGX_GetParam("SCRIPT_NAME", this->req.envp),
                                        NULL, NULL, 0, 0);
 }
        
@@ -193,14 +221,24 @@ static void redirect(private_request_t *this, char *fmt, ...)
 {
        va_list args;
 
-       FCGX_FPrintF(this->req->out, "Status: 303 See Other\n");
-       FCGX_FPrintF(this->req->out, "Location: %s%s",
-                                FCGX_GetParam("SCRIPT_NAME", this->req->envp),
+       FCGX_FPrintF(this->req.out, "Status: 303 See Other\n");
+       FCGX_FPrintF(this->req.out, "Location: %s%s",
+                                FCGX_GetParam("SCRIPT_NAME", this->req.envp),
                                 *fmt == '/' ? "" : "/");
        va_start(args, fmt);
-       FCGX_VFPrintF(this->req->out, fmt, args);
+       FCGX_VFPrintF(this->req.out, fmt, args);
        va_end(args);
-       FCGX_FPrintF(this->req->out, "\n\n");
+       FCGX_FPrintF(this->req.out, "\n\n");
+}
+
+/**
+ * Implementation of request_t.to_referer.
+ */
+static void to_referer(private_request_t *this)
+{
+       FCGX_FPrintF(this->req.out, "Status: 303 See Other\n");
+       FCGX_FPrintF(this->req.out, "Location: %s\n\n",
+                                FCGX_GetParam("HTTP_REFERER", this->req.envp));
 }
 
 /**
@@ -208,7 +246,23 @@ static void redirect(private_request_t *this, char *fmt, ...)
  */
 static char* get_base(private_request_t *this)
 {
-       return FCGX_GetParam("SCRIPT_NAME", this->req->envp);
+       return FCGX_GetParam("SCRIPT_NAME", this->req.envp);
+}
+       
+/**
+ * Implementation of request_t.session_closed.
+ */
+static bool session_closed(private_request_t *this)
+{
+       return this->closed;
+}
+
+/**
+ * Implementation of request_t.close_session.
+ */
+static void close_session(private_request_t *this)
+{
+       this->closed = TRUE;
 }
 
 /**
@@ -216,9 +270,9 @@ static char* get_base(private_request_t *this)
  */
 static void serve(private_request_t *this, char *headers, chunk_t chunk)
 {
-       FCGX_FPrintF(this->req->out, "%s\n\n", headers);
+       FCGX_FPrintF(this->req.out, "%s\n\n", headers);
 
-       FCGX_PutStr(chunk.ptr, chunk.len, this->req->out);
+       FCGX_PutStr(chunk.ptr, chunk.len, this->req.out);
 }
 
 /**
@@ -228,6 +282,7 @@ static void render(private_request_t *this, char *template)
 {
        NEOERR* err;
        
+       pthread_setspecific(this_key, this);
        err = cgi_display(this->cgi, template);
        if (err)
        {
@@ -237,6 +292,25 @@ static void render(private_request_t *this, char *template)
        return;
 }
 
+/**
+ * Implementation of request_t.streamf.
+ */
+static int streamf(private_request_t *this, char *format, ...)
+{
+       va_list args;
+       int written;
+
+       va_start(args, format);
+       written = FCGX_VFPrintF(this->req.out, format, args);
+       va_end(args);
+       if (written >= 0 &&
+               FCGX_FFlush(this->req.out) == -1)
+       {
+               return -1;
+       }
+       return written;
+}
+
 /**
  * Implementation of request_t.set.
  */
@@ -255,6 +329,15 @@ static void setf(private_request_t *this, char *format, ...)
        va_start(args, format);
        hdf_set_valuevf(this->hdf, format, args);
        va_end(args);
+}      
+       
+/**
+ * Implementation of request_t.get_ref.
+ */
+static request_t* get_ref(private_request_t *this)
+{
+       ref_get(&this->ref);
+       return &this->public;
 }
 
 /**
@@ -262,8 +345,13 @@ static void setf(private_request_t *this, char *format, ...)
  */
 static void destroy(private_request_t *this)
 {
-       cgi_destroy(&this->cgi);
-       free(this);
+       if (ref_put(&this->ref))
+       {
+               pthread_setspecific(this_key, this);
+               cgi_destroy(&this->cgi);
+               FCGX_Finish_r(&this->req);
+               free(this);
+       }
 }
 
 /**
@@ -274,43 +362,60 @@ static void init(void)
 {
        cgiwrap_init_emu(NULL, read_cb, writef_cb, write_cb,
                         getenv_cb, putenv_cb, iterenv_cb);
-       pthread_key_create(&req_key, NULL);
-       pthread_key_create(&req_env_len_key, NULL);
+       pthread_key_create(&this_key, NULL);
 }
 
 /*
  * see header file
  */
-request_t *request_create(FCGX_Request *request, bool debug)
+request_t *request_create(int fd, bool debug)
 {
        NEOERR* err;
        private_request_t *this = malloc_thing(private_request_t);
+       bool failed = FALSE;
+       
+       pthread_cleanup_push(free, this);
+       if (FCGX_InitRequest(&this->req, fd, 0) != 0 ||
+               FCGX_Accept_r(&this->req) != 0)
+       {
+               failed = TRUE;
+       }
+       pthread_cleanup_pop(failed);
+       if (failed)
+       {
+               return NULL;
+       }
 
        this->public.get_path = (char*(*)(request_t*))get_path;
        this->public.get_base = (char*(*)(request_t*))get_base;
+       this->public.get_host = (char*(*)(request_t*))get_host;
+       this->public.get_user_agent = (char*(*)(request_t*))get_user_agent;
        this->public.add_cookie = (void(*)(request_t*, char *name, char *value))add_cookie;
        this->public.get_cookie = (char*(*)(request_t*,char*))get_cookie;
        this->public.get_query_data = (char*(*)(request_t*, char *name))get_query_data;
+       this->public.session_closed = (bool(*)(request_t*))session_closed;
+       this->public.close_session = (void(*)(request_t*))close_session;
        this->public.redirect = (void(*)(request_t*, char *fmt,...))redirect;
+       this->public.to_referer = (void(*)(request_t*))to_referer;
        this->public.render = (void(*)(request_t*,char*))render;
+       this->public.streamf = (int(*)(request_t*, char *format, ...))streamf;
        this->public.serve = (void(*)(request_t*,char*,chunk_t))serve;
        this->public.set = (void(*)(request_t*, char *, char*))set;
        this->public.setf = (void(*)(request_t*, char *format, ...))setf;
+       this->public.get_ref = (request_t*(*)(request_t*))get_ref;
        this->public.destroy = (void(*)(request_t*))destroy;
        
        pthread_once(&once, init);
+       pthread_setspecific(this_key, this);
        
-       this->req = request;
-       pthread_setspecific(req_key, (void*)request);
-       
-       int req_env_len = 0;
-       while (request->envp[req_env_len] != NULL)
+       this->ref = 1;
+       this->closed = FALSE;
+       this->req_env_len = 0;  
+       while (this->req.envp[this->req_env_len] != NULL)
        {
-               req_env_len++;
+               this->req_env_len++;
        }
        
-       pthread_setspecific(req_env_len_key, (void*)req_env_len);
-       
        err = hdf_init(&this->hdf);
        if (!err)
        {
@@ -335,6 +440,7 @@ request_t *request_create(FCGX_Request *request, bool debug)
                }
        }
        nerr_log_error(err);
+       FCGX_Finish_r(&this->req);
        free(this);
        return NULL;
 }
similarity index 55%
rename from src/manager/lib/request.h
rename to src/libfast/request.h
index f78741d379a2f61978c83f55392881f02f75f133..d73477a5a86df84797cde3804b1188b238d58b9f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file request.h
- * 
- * @brief Interface of request_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 request request
+ * @{ @ingroup libfast
  */
 
 #ifndef REQUEST_H_
 typedef struct request_t request_t;
 
 /**
- * @brief A HTTP request, encapsulates FCGX_Request.
+ * A HTTP request, encapsulates FCGX_Request.
  *
+ * The response is also handled through the request object.
  */
 struct request_t {
        
        /**
-        * @brief Add a cookie to the reply (Set-Cookie header).
+        * Add a cookie to the reply (Set-Cookie header).
         *
-        * @param name                  name of the cookie to set
-        * @param value                 value of the cookie
+        * @param name          name of the cookie to set
+        * @param value         value of the cookie
         */
        void (*add_cookie)(request_t *this, char *name, char *value);
        
        /**
-        * @brief Get a cookie the client sent in the request.
+        * Get a cookie the client sent in the request.
         *
         * @param name          name of the cookie
         * @return                      cookie value, NULL if no such cookie found
@@ -51,21 +52,35 @@ struct request_t {
        char* (*get_cookie)(request_t *this, char *name);
        
        /**
-        * @brief Get the request path relative to the application.
+        * Get the request path relative to the application.
         *
         * @return                      path
         */
        char* (*get_path)(request_t *this);
        
        /**
-        * @brief Get the base path of the application.
+        * Get the base path of the application.
         *
         * @return                      base path
         */
        char* (*get_base)(request_t *this);
        
        /**
-        * @brief Get a post/get variable included in the request.
+        * Get the remote host address of this request.
+        *
+        * @return                      host address as string
+        */
+       char* (*get_host)(request_t *this);
+       
+       /**
+        * Get the user agent string.
+        *
+        * @return                      user agent string
+        */
+       char* (*get_user_agent)(request_t *this);
+               
+       /**
+        * Get a post/get variable included in the request.
         *
         * @param name          name of the POST/GET variable
         * @return                      value, NULL if not found
@@ -73,7 +88,19 @@ struct request_t {
        char* (*get_query_data)(request_t *this, char *name);
        
        /**
-        * @brief Redirect the client to another location.
+        * Close the session and it's context after handling.
+        */
+       void (*close_session)(request_t *this);
+       
+       /**
+        * Has the session been closed by close_session()?
+        *
+        * @return                      TRUE if session has been closed
+        */
+       bool (*session_closed)(request_t *this);
+       
+       /**
+        * Redirect the client to another location.
         *
         * @param fmt           location format string
         * @param ...           variable argument for fmt
@@ -81,7 +108,12 @@ struct request_t {
        void (*redirect)(request_t *this, char *fmt, ...);
        
        /**
-        * @brief Set a template value.
+        * Redirect the client to the referer.
+        */
+       void (*to_referer)(request_t *this);
+               
+       /**
+        * Set a template value.
         *
         * @param key           key to set
         * @param value         value to set key to
@@ -89,7 +121,7 @@ struct request_t {
        void (*set)(request_t *this, char *key, char *value);
        
        /**
-        * @brief Set a template value using format strings.
+        * Set a template value using format strings.
         *
         * Format string is in the form "key=value", where printf like format
         * substitution occurs over the whole string.
@@ -100,7 +132,7 @@ struct request_t {
        void (*setf)(request_t *this, char *format, ...);
        
        /**
-        * @brief Render a template.
+        * Render a template.
         *
         * The render() function additionally sets a HDF variable "base"
         * which points to the root of the web application and allows to point to
@@ -111,7 +143,19 @@ struct request_t {
        void (*render)(request_t *this, char *template);
        
        /**
-        * @brief Serve a request with headers and a body.
+        * Stream a format string to the client.
+        *
+        * Stream is not closed and may be called multiple times to allow
+        * server-push functionality.
+        *
+        * @param format        printf like format string
+        * @param ...           argmuent list to format string
+        * @return                      number of streamed bytes, < 0 if stream closed
+        */
+       int (*streamf)(request_t *this, char *format, ...);
+       
+       /**
+        * Serve a request with headers and a body.
         *
         * @param headers       HTTP headers, \n separated
         * @param chunk         body to write to output
@@ -119,17 +163,24 @@ struct request_t {
        void (*serve)(request_t *this, char *headers, chunk_t chunk);
        
        /**
-        * @brief Destroy the request_t.
+        * Increase the reference count to the stream.
+        *
+        * @return                      this with increased refcount
+        */
+       request_t* (*get_ref)(request_t *this);
+       
+       /**
+        * Destroy the request_t.
         */
        void (*destroy) (request_t *this);
 };
 
 /**
- * @brief Create a request from the fastcgi struct.
+ * Create a request from the fastcgi struct.
  *
- * @param request              the FCGI request
+ * @param fd                   file descripter opened with FCGX_OpenSocket
  * @param debug                        no stripping, no compression, timing information
  */
-request_t *request_create(FCGX_Request *request, bool debug);
+request_t *request_create(int fd, bool debug);
 
-#endif /* REQUEST_H_ */
+#endif /* REQUEST_H_ @} */
similarity index 76%
rename from src/manager/lib/session.c
rename to src/libfast/session.c
index fe260b887815e505c5269dc70278d55f1f8752e9..519187efa4cd9ff2293cd193ba53123032ea7910 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file session.c
- *
- * @brief Implementation of session_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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
@@ -53,6 +48,11 @@ struct private_session_t {
         */
        linked_list_t *controllers;
        
+       /**
+        * list of filter instances filter_t
+        */
+       linked_list_t *filters;
+       
        /**
         * user defined session context
         */
@@ -60,13 +60,21 @@ struct private_session_t {
 };
 
 /**
- * Implementation of session_t.load_controller.
+ * Implementation of session_t.add_controller.
  */
 static void add_controller(private_session_t *this, controller_t *controller)
 {
        this->controllers->insert_last(this->controllers, controller);
 }
 
+/**
+ * Implementation of session_t.add_filter.
+ */
+static void add_filter(private_session_t *this, filter_t *filter)
+{
+       this->filters->insert_last(this->filters, filter);
+}
+
 /**
  * Create a session ID and a cookie
  */
@@ -82,6 +90,28 @@ static void create_sid(private_session_t *this, request_t *request)
        randomizer->destroy(randomizer);
 }
 
+/**
+ * run all registered filters
+ */
+static bool run_filter(private_session_t *this, request_t *request,
+                                          controller_t *controller)
+{
+       iterator_t *iterator;
+       filter_t *filter;
+       
+       iterator = this->filters->create_iterator(this->filters, TRUE);
+       while (iterator->iterate(iterator, (void**)&filter))
+       {
+               if (!filter->run(filter, request, controller))
+               {
+                       iterator->destroy(iterator);
+                       return FALSE;
+               }
+       }
+       iterator->destroy(iterator);
+       return TRUE;
+}
+
 /**
  * Implementation of session_t.process.
  */
@@ -113,9 +143,12 @@ static void process(private_session_t *this, request_t *request)
                {
                        if (streq(current->get_name(current), param[0]))
                        {       
-                               current->handle(current, request, param[1], param[2], param[3],
-                                                               param[4], param[5]);
-                               handled = TRUE;
+                               if (run_filter(this, request, current))
+                               {
+                                       current->handle(current, request, param[1], param[2],
+                                                                       param[3], param[4], param[5]);
+                                       handled = TRUE;
+                               }
                                break;
                        }
                }
@@ -149,6 +182,7 @@ static char* get_sid(private_session_t *this)
 static void destroy(private_session_t *this)
 {
        this->controllers->destroy_offset(this->controllers, offsetof(controller_t, destroy));
+       this->filters->destroy_offset(this->filters, offsetof(filter_t, destroy));
        if (this->context) this->context->destroy(this->context);
        free(this->sid);
        free(this);
@@ -162,12 +196,14 @@ session_t *session_create(context_t *context)
        private_session_t *this = malloc_thing(private_session_t);
 
        this->public.add_controller = (void(*)(session_t*, controller_t*))add_controller;
+       this->public.add_filter = (void(*)(session_t*, filter_t*))add_filter;
        this->public.process = (void(*)(session_t*,request_t*))process;
        this->public.get_sid = (char*(*)(session_t*))get_sid;
        this->public.destroy = (void(*)(session_t*))destroy;
 
        this->sid = NULL;
        this->controllers = linked_list_create();
+       this->filters = linked_list_create();
        this->context = context;
        
        return &this->public;
similarity index 68%
rename from src/manager/lib/session.h
rename to src/libfast/session.h
index d18545876f690dba957a11b8a4ac5961d24b242d..98d7ee3ce920401cd19014fe884684affc707064 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file session.h
- * 
- * @brief Interface of session_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 session session
+ * @{ @ingroup libfast
  */
 
 #ifndef SESSION_H_
 
 #include "request.h"
 #include "controller.h"
+#include "filter.h"
 
 typedef struct session_t session_t;
 
 /**
- * @brief A session, identified by a session ID.
- *
+ * Session handling class, instanciated for each user session.
  */
 struct session_t {
        
        /**
-        * @brief Get the session ID of the session.
+        * Get the session ID of the session.
         *
         * @return                              session ID
         */
        char* (*get_sid)(session_t *this);
        
        /**
-        * @brief Add a controller instance to the session.
+        * Add a controller instance to the session.
         *
         * @param controller    controller to add
         */
        void (*add_controller)(session_t *this, controller_t *controller);
        
        /**
-        * @brief Process a request in this session.
+        * @brief Add a filter instance to the session.
+        *
+        * @param filter                filter to add
+        */
+       void (*add_filter)(session_t *this, filter_t *filter);
+       
+       /**
+        * Process a request in this session.
         *
         * @param request               request to process
         */
        void (*process)(session_t *this, request_t *request);
        
        /**
-        * @brief Destroy the session_t.
+        * Destroy the session_t.
         *
         * @param this                  calling object
         */
@@ -64,10 +71,10 @@ struct session_t {
 };
 
 /**
- * @brief Create a session.
+ * Create a session new session.
  *
- * @param context                              user defined session context instance
+ * @param context              user defined session context instance
  */
 session_t *session_create(context_t *context);
 
-#endif /* SESSION_H_ */
+#endif /* SESSION_H_ @} */
index fc642c6152bef4e17559799f1770d00107fbf40e..b858e25853032d8980987ac84fd90259aea9cf6b 100644 (file)
@@ -9,43 +9,37 @@ else
 endif
 
 libstrongswan_la_SOURCES += \
-credential_store.h \
 library.c library.h \
 chunk.c chunk.h \
 debug.c debug.h \
 enum.c enum.h \
+settings.h settings.c \
 printf_hook.c printf_hook.h \
 asn1/asn1.c asn1/asn1.h \
 asn1/oid.c asn1/oid.h \
 asn1/pem.c asn1/pem.h \
 asn1/ttodata.c asn1/ttodata.h \
-crypto/ac.c crypto/ac.h \
-crypto/ca.c crypto/ca.h \
-crypto/certinfo.c crypto/certinfo.h \
-crypto/crl.c crypto/crl.h \
 crypto/crypters/crypter.c crypto/crypters/crypter.h \
-crypto/crypters/aes_cbc_crypter.c crypto/crypters/aes_cbc_crypter.h \
-crypto/crypters/des_crypter.c crypto/crypters/des_crypter.h \
-crypto/diffie_hellman.c crypto/diffie_hellman.h \
 crypto/hashers/hasher.h crypto/hashers/hasher.c \
-crypto/hashers/sha1_hasher.c crypto/hashers/sha1_hasher.h \
-crypto/hashers/sha2_hasher.c crypto/hashers/sha2_hasher.h \
-crypto/hashers/md5_hasher.c  crypto/hashers/md5_hasher.h \
-crypto/hmac.c crypto/hmac.h \
-crypto/ietf_attr_list.c crypto/ietf_attr_list.h \
-crypto/ocsp.c crypto/ocsp.h \
-crypto/pkcs7.c crypto/pkcs7.h \
 crypto/pkcs9.c crypto/pkcs9.h \
-crypto/prfs/fips_prf.c crypto/prfs/fips_prf.h \
-crypto/prfs/hmac_prf.c crypto/prfs/hmac_prf.h \
 crypto/prfs/prf.c crypto/prfs/prf.h \
 crypto/prf_plus.h crypto/prf_plus.c \
-crypto/rsa/rsa_private_key.c crypto/rsa/rsa_private_key.h \
-crypto/rsa/rsa_public_key.h  crypto/rsa/rsa_public_key.c \
-crypto/signers/hmac_signer.c crypto/signers/hmac_signer.h \
 crypto/signers/signer.c crypto/signers/signer.h \
-crypto/x509.c crypto/x509.h \
-utils/fetcher.c utils/fetcher.h \
+crypto/diffie_hellman.c crypto/diffie_hellman.h \
+crypto/crypto_factory.c crypto/crypto_factory.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 \
+credentials/keys/public_key.c credentials/keys/public_key.h \
+credentials/keys/shared_key.c credentials/keys/shared_key.h \
+credentials/certificates/certificate.c credentials/certificates/certificate.h \
+credentials/certificates/x509.h credentials/certificates/x509.c \
+credentials/certificates/crl.h credentials/certificates/crl.c \
+credentials/certificates/ocsp_request.h credentials/certificates/ocsp_request.c \
+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 \
@@ -54,28 +48,22 @@ utils/lexparser.c utils/lexparser.h \
 utils/linked_list.c utils/linked_list.h \
 utils/enumerator.c utils/enumerator.h \
 utils/optionsfrom.c utils/optionsfrom.h \
-utils/randomizer.c utils/randomizer.h
+utils/randomizer.c utils/randomizer.h \
+utils/mutex.c utils/mutex.h \
+plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h
 
 if USE_INTEGRITY_TEST
   libstrongswan_la_SOURCES += \
   fips/fips_canister_end.c
 endif
 
-libstrongswan_la_LIBADD = -lgmp -lpthread
+libstrongswan_la_LIBADD = -lpthread -ldl
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan
+AM_CFLAGS =
 
 if USE_LEAK_DETECTIVE
-  libstrongswan_la_LIBADD += -ldl
-  AM_CFLAGS = -DLEAK_DETECTIVE
-endif
-
-if USE_LIBCURL
-  libstrongswan_la_LIBADD += -lcurl
-endif
-
-if USE_LIBLDAP
-  libstrongswan_la_LIBADD += -lldap -llber
+  AM_CFLAGS += -DLEAK_DETECTIVE
 endif
 
 EXTRA_DIST = asn1/oid.txt asn1/oid.pl
@@ -88,6 +76,65 @@ asn1/oid.c : asn1/oid.txt asn1/oid.pl
 asn1/oid.h :   asn1/oid.txt asn1/oid.pl
                cd asn1 && $(PERL) oid.pl
 
+
+# build plugins with their own Makefile
+#######################################
+
+SUBDIRS = 
+
+if USE_AES
+  SUBDIRS += plugins/aes
+endif
+
+if USE_DES
+  SUBDIRS += plugins/des
+endif
+
+if USE_MD5
+  SUBDIRS += plugins/md5
+endif
+
+if USE_SHA1
+  SUBDIRS += plugins/sha1
+endif
+
+if USE_SHA2
+  SUBDIRS += plugins/sha2
+endif
+
+if USE_FIPS_PRF
+  SUBDIRS += plugins/fips_prf
+endif
+
+if USE_GMP
+  SUBDIRS += plugins/gmp
+endif
+
+if USE_HMAC
+  SUBDIRS += plugins/hmac
+endif
+
+if USE_X509
+  SUBDIRS += plugins/x509
+endif
+
+if USE_CURL
+  SUBDIRS += plugins/curl
+endif
+
+if USE_LDAP
+  SUBDIRS += plugins/ldap
+endif
+
+if USE_MYSQL
+  SUBDIRS += plugins/mysql
+endif
+
+if USE_SQLITE
+  SUBDIRS += plugins/sqlite
+endif
+
+
 if USE_INTEGRITY_TEST
 # build fips_signer which in turn builds fips_signature.h
 #########################################################
index b53f5a7665c9826978e71e53b149efa2d236641e..cd204c698126b7ed6d34656c26d88fc92aa99857 100644 (file)
@@ -1,14 +1,6 @@
-/**
- * @file asn1.c
- *
- * @brief Simple ASN.1 parser
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Will
  * Copyright (C) 2000-2008 Andreas Steffen
- *
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -21,7 +13,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
  */
 
 #include <stdio.h>
@@ -833,20 +825,6 @@ chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
        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 */
-       chunk_t n;
-
-       n.len = 1 + bits / 8;  /* size in bytes */      
-       n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
-
-       return asn1_wrap(ASN1_INTEGER, "m", n);
-}
-
 /**
  * ASN.1 definition of time
  */
index 4eaf1a78d3c835b717d4b4ad0b75837deefac9b6..43221476625e0ba6a51f6d818fbe3ad9da03ab24 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file asn1.h
- *
- * @brief Simple ASN.1 parser
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Will
  * Copyright (C) 2000-2008 Andreas Steffen
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
+ */
+/**
+ * @defgroup asn1 asn1
+ * @{ @ingroup asn1
  */
 
-#ifndef _ASN1_H
-#define _ASN1_H
+#ifndef ASN1_H_
+#define ASN1_H_
 
 #include <stdarg.h>
 #include <gmp.h>
@@ -35,9 +33,7 @@
 
 
 /**
- * @brief Definition of some primitive ASN1 types
- *
- * @ingroup asn1
+ * Definition of some primitive ASN1 types
  */
 typedef enum {
     ASN1_EOC =                         0x00,
@@ -87,7 +83,6 @@ typedef enum {
 } asn1_t;
 
 /* Definition of ASN1 flags */
-
 #define ASN1_NONE      0x00
 #define ASN1_DEF       0x01
 #define ASN1_OPT       0x02
@@ -100,7 +95,6 @@ typedef enum {
 #define ASN1_INVALID_LENGTH    0xffffffff
 
 /* definition of an ASN.1 object */
-
 typedef struct {
        u_int   level;
        const u_char  *name;
@@ -141,9 +135,8 @@ extern bool is_asn1(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_bitstring(const char *mode, chunk_t content);
 extern chunk_t asn1_wrap(asn1_t type, const char *mode, ...);
 
-#endif /* _ASN1_H */
+#endif /* ASN1_H_ @}*/
index 4ab70dbdc4fd4705968988a1d1ec75c8d978b150..f545d7a077b2360979d5c2a2e68365c70fdd04ab 100755 (executable)
@@ -11,7 +11,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
  */
 
 #include <stdio.h>
@@ -95,10 +95,16 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s
        u_int8_t padding, *last_padding_pos, *first_padding_pos;
        
        if (passphrase == NULL || passphrase->len == 0)
+       {
                return "missing passphrase";
+       }
 
        /* build key from passphrase and IV */
-       hasher = hasher_create(HASH_MD5);
+       hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
+       if (hasher == NULL)
+       {
+               return "MD5 hasher not supported";
+       }
        hash.len = hasher->get_hash_size(hasher);
        hash.ptr = alloca(hash.len);
        hasher->get_hash(hasher, *passphrase, NULL);
@@ -115,7 +121,7 @@ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_s
        hasher->destroy(hasher);
        
        /* decrypt blob */
-       crypter = crypter_create(alg, key_size);
+       crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
        crypter->set_key(crypter, key);
        if (crypter->decrypt(crypter, *blob, *iv, &decrypted) != SUCCESS)
        {
@@ -310,8 +316,8 @@ err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
 /* load a coded key or certificate file with autodetection
  * of binary DER or base64 PEM ASN.1 formats and armored PGP format
  */
-bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
-                                               const char *type, chunk_t *blob, bool *pgp)
+bool pem_asn1_load_file(char *filename, chunk_t *passphrase,
+                                               chunk_t *blob, bool *pgp)
 {
        err_t ugh = NULL;
 
@@ -326,7 +332,7 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
                blob->ptr = malloc(blob->len);
                bytes = fread(blob->ptr, 1, blob->len, fd);
                fclose(fd);
-               DBG1("  loading %s file '%s' (%d bytes)", type, filename, bytes);
+               DBG2("  loading '%s' (%d bytes)", filename, bytes);
 
                *pgp = FALSE;
 
@@ -364,7 +370,7 @@ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
        }
        else
        {
-               DBG1("  could not open %s file '%s'", type, filename);
+               DBG1("  reading file '%s' failed", filename);
        }
        return FALSE;
 }
index 0f4b7202c35bddb9377144590213e3e584d10425..956623c0d34bd07e84adec9ccbdefa28d230b85c 100755 (executable)
@@ -21,7 +21,7 @@
 
 err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp);
 
-bool pem_asn1_load_file(const char *filename, chunk_t *passphrase,
-                                               const char *type, chunk_t *blob, bool *pgp);
+bool pem_asn1_load_file(char *filename, chunk_t *passphrase,
+                                               chunk_t *blob, bool *pgp);
 
-#endif /*PEM_H_*/
+#endif /*PEM_H_ @} */
index 125313c2a53b96987604d7f2ccefbc81fa3f78f9..6cffecd40c134e66f8798a58648099d786d5bd7f 100644 (file)
@@ -11,6 +11,8 @@
  * 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$
  */
 
 #include "ttodata.h"
@@ -34,7 +36,7 @@ static const char *badch(const char *, int, char *, size_t);
 #define        BADOFF(code) (BADCH0-(code))
 
 /**
- * @brief convert text to data, with verbose error reports
+ * convert text to data, with verbose error reports
  * 
  * If some of this looks slightly odd, it's because it has changed
  * repeatedly (from the original atodata()) without a major rewrite.
@@ -197,7 +199,7 @@ const char *ttodatav(const char *src, size_t srclen, int base, char *dst, size_t
 }
 
 /**
- * @brief ttodata - convert text to data
+ * ttodata - convert text to data
  * 
  * @param src
  * @param srclen       0 means apply strlen()
@@ -214,7 +216,7 @@ const char *ttodata(const char *src, size_t srclen, int base, char *dst, size_t
 }
 
 /**
- * @brief atodata - convert ASCII to data
+ * atodata - convert ASCII to data
  * 
  * backward-compatibility interface
  * 
@@ -234,7 +236,7 @@ size_t atodata(const char *src, size_t srclen, char *dst, size_t dstlen)
 }
 
 /**
- * @brief  atobytes - convert ASCII to data bytes
+ *  atobytes - convert ASCII to data bytes
  *
  * another backward-compatibility interface
  */
@@ -244,7 +246,7 @@ const char *atobytes(const char *src, size_t srclen, char *dst, size_t dstlen, s
 }
 
 /**
- * @brief unhex - convert two ASCII hex digits to byte
+ * unhex - convert two ASCII hex digits to byte
  * 
  * @param src          known to be full length
  * @param dstnumber of result bytes, or error code
@@ -290,7 +292,7 @@ static int unhex(const char *src, char *dst, size_t dstlen)
 }
 
 /**
- * @brief unb64 - convert four ASCII base64 digits to three bytes
+ * unb64 - convert four ASCII base64 digits to three bytes
  *
  * Note that a base64 digit group is padded out with '=' if it represents
  * less than three bytes:  one byte is dd==, two is ddd=, three is dddd.
@@ -368,7 +370,7 @@ static int unb64(const char *src, char *dst, size_t dstlen)
 }
 
 /**
- * @brief untext - convert one ASCII character to byte
+ * untext - convert one ASCII character to byte
  * 
  * @param src          known to be full length
  * @param dst          
@@ -386,7 +388,7 @@ static int untext(const char *src, char *dst, size_t dstlen)
 }
 
 /**
- * @brief badch - produce a nice complaint about an unknown character
+ * badch - produce a nice complaint about an unknown character
  *
  * If the compiler complains that the array bigenough[] has a negative
  * size, that means the TTODATAV_BUF constant has been set too small.
index 6125c6b82f0fd145212297cb224c3f9253f52f38..89ce53b848241d9711fb3e8b92243b9b56bcec2e 100644 (file)
@@ -25,4 +25,4 @@
 err_t ttodata(const char *src, size_t srclen, int base, char *buf, size_t buflen, size_t *needed);
 
 
-#endif /* TTODATA_H_ */
+#endif /* TTODATA_H_ @} */
index 0d78416413013103e7b0c313cb11e167b7c1fbeb..6f12c9b5165908ad0c910661604d2ea02404cd61 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file chunk.c
- *
- * @brief Pointer/lenght abstraction and its functions.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
@@ -356,82 +351,22 @@ bool chunk_equals_or_null(chunk_t a, chunk_t b)
        return a.len == b.len && memeq(a.ptr, b.ptr, a.len);
 }
 
-/**
- * Number of bytes per line to dump raw data
- */
-#define BYTES_PER_LINE 16
-
-/**
- * output handler in printf() for byte ranges
- */
-static int print_bytes(FILE *stream, const struct printf_info *info,
-                                          const void *const *args)
-{
-       char *bytes = *((void**)(args[0]));
-       int len = *((size_t*)(args[1]));
-       
-       char buffer[BYTES_PER_LINE * 3];
-       char ascii_buffer[BYTES_PER_LINE + 1];
-       char *buffer_pos = buffer;
-       char *bytes_pos  = bytes;
-       char *bytes_roof = bytes + len;
-       int line_start = 0;
-       int i = 0;
-       int written = 0;
-       
-       written += fprintf(stream, "=> %d bytes @ %p", len, bytes);
-       
-       while (bytes_pos < bytes_roof)
-       {
-               *buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF];
-               *buffer_pos++ = hexdig_upper[ *bytes_pos       & 0xF];
-
-               ascii_buffer[i++] =
-                               (*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.';
-
-               if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE) 
-               {
-                       int padding = 3 * (BYTES_PER_LINE - i);
-                       int written;
-                       
-                       while (padding--)
-                       {
-                               *buffer_pos++ = ' ';
-                       }
-                       *buffer_pos++ = '\0';
-                       ascii_buffer[i] = '\0';
-                       
-                       written += fprintf(stream, "\n%4d: %s  %s",
-                                                          line_start, buffer, ascii_buffer);
-
-                       
-                       buffer_pos = buffer;
-                       line_start += BYTES_PER_LINE;
-                       i = 0;
-               }
-               else
-               {
-                       *buffer_pos++ = ' ';
-               }
-       }
-       return written;
-}
-
 /**
  * output handler in printf() for chunks
  */
-static int print_chunk(FILE *stream, const struct printf_info *info,
+static int chunk_print(FILE *stream, const struct printf_info *info,
                                           const void *const *args)
 {
        chunk_t *chunk = *((chunk_t**)(args[0]));
        bool first = TRUE;
        chunk_t copy = *chunk;
        int written = 0;
+       printf_hook_functions_t mem = mem_get_printf_hooks();
        
        if (!info->alt)
        {
                const void *new_args[] = {&chunk->ptr, &chunk->len};
-               return print_bytes(stream, info, new_args);
+               return mem.print(stream, info, new_args);
        }
        
        while (copy.len > 0)
@@ -451,10 +386,24 @@ static int print_chunk(FILE *stream, const struct printf_info *info,
 }
 
 /**
- * register printf() handlers
+ * arginfo handler for printf() mem ranges
+ */
+static int chunk_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+       if (n > 0)
+       {
+               argtypes[0] = PA_POINTER;
+       }
+       return 1;
+}
+
+/**
+ * return printf hook functions for a chunk
  */
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t chunk_get_printf_hooks()
 {
-       register_printf_function(PRINTF_CHUNK, print_chunk, arginfo_ptr);
-       register_printf_function(PRINTF_BYTES, print_bytes, arginfo_ptr_int);
+       printf_hook_functions_t hooks = {chunk_print, chunk_arginfo};
+       
+       return hooks;
 }
+
index 9c0aabba1153ecbd3c7a5cda3e380e9a13346ce6..76acfde348a8455d6eb3f7e8003cebe56f639c31 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file chunk.h
- *
- * @brief Pointer/length abstraction and its functions.
- *
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * WITHOUT ANY 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 chunk chunk
+ * @{ @ingroup libstrongswan
  */
 
 #ifndef CHUNK_H_
@@ -26,8 +26,7 @@
 
 #include <string.h>
 #include <stdarg.h>
-
-#include <library.h>
+#include <sys/types.h>
 
 typedef struct chunk_t chunk_t;
 
@@ -41,6 +40,8 @@ struct chunk_t {
        size_t len;
 };
 
+#include <library.h>
+
 /**
  * A { NULL, 0 }-chunk handy for initialization.
  */
@@ -161,4 +162,12 @@ bool chunk_equals(chunk_t a, chunk_t b);
  */
 bool chunk_equals_or_null(chunk_t a, chunk_t b);
 
-#endif /* CHUNK_H_ */
+/**
+ * Get printf hooks for a chunk.
+ *
+ * Arguments are: 
+ *    chunk_t *chunk
+ */
+printf_hook_functions_t chunk_get_printf_hooks();
+
+#endif /* CHUNK_H_ @}*/
diff --git a/src/libstrongswan/credential_store.h b/src/libstrongswan/credential_store.h
deleted file mode 100755 (executable)
index 62b6ad2..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/**
- * @file credential_store.h
- * 
- * @brief Interface credential_store_t.
- *  
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifndef CREDENTIAL_STORE_H_
-#define CREDENTIAL_STORE_H_
-
-typedef struct credential_store_t credential_store_t;
-
-#include <library.h>
-#include <crypto/x509.h>
-#include <crypto/ca.h>
-#include <crypto/rsa/rsa_private_key.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <utils/identification.h>
-
-
-/**
- * @brief The interface for a credential_store backend.
- *
- * @b Constructors:
- *  - stroke_create()
- *
- * @ingroup config
- */
-struct credential_store_t { 
-
-       /**
-        * @brief Returns the secret shared by two specific IDs.
-        * 
-        * The returned chunk must be destroyed by the caller after usage.
-        * 
-        * @param this                                  calling object
-        * @param my_id                                 my ID identifiying the secret.
-        * @param other_id                              peer ID identifying the secret.
-        * @param[out] secret                   the pre-shared secret will be written there.
-        * @return
-        *                                                              - NOT_FOUND     if no preshared secrets for specific ID could be found
-        *                                                              - SUCCESS
-        *
-        */     
-       status_t (*get_shared_key) (credential_store_t *this, identification_t *my_id,
-                                                               identification_t *other_id, chunk_t *shared_key);
-       
-       /**
-        * @brief Returns the EAP secret for two specified IDs.
-        * 
-        * The returned chunk must be destroyed by the caller after usage.
-        * 
-        * @param this                                  calling object
-        * @param my_id                                 my ID identifiying the secret.
-        * @param other_id                              peer ID identifying the secret.
-        * @param[out] eap_key                  the EAP secret will be written here
-        * @return
-        *                                                              - NOT_FOUND     if no preshared secrets for specific ID could be found
-        *                                                              - SUCCESS
-        *
-        */     
-       status_t (*get_eap_key) (credential_store_t *this, identification_t *my_id,
-                                                        identification_t *other_id, chunk_t *eap_key);
-       
-       /**
-        * @brief Returns the RSA public key of a specific ID.
-        * 
-        * @param this                                  calling object
-        * @param id                                    identification_t object identifiying the key.
-        * @return                                              public key, or NULL if not found
-        */
-       rsa_public_key_t* (*get_rsa_public_key) (credential_store_t *this, identification_t *id);
-       
-       /**
-        * @brief Is there a matching RSA private key belonging to an RSA public key?
-        * 
-        * @param this                                  calling object
-        * @param pubkey                                public key 
-        * @return                                              TRUE if matching private key was found 
-        */     
-       bool (*has_rsa_private_key) (credential_store_t *this, rsa_public_key_t *pubkey);
-
-       /**
-        * @brief Returns the certificate of a specific ID.
-        * 
-        * @param this                                  calling object
-        * @param id                                    identification_t object identifiying the cert.
-        * @return                                              certificate, or NULL if not found
-        */
-       x509_t* (*get_certificate) (credential_store_t *this, identification_t *id);
-       
-       /**
-        * @brief Returns the auth certificate of a specific subject distinguished name.
-        * 
-        * @param this                                  calling object
-        * @param auth_flags                    set of allowed authority types
-        * @param id                                    identification_t object identifiying the cacert.
-        * @return                                              certificate, or NULL if not found
-        */
-       x509_t* (*get_auth_certificate) (credential_store_t *this, u_int auth_flags, identification_t *id);
-       
-       /**
-        * @brief Returns the ca certificate of a specific keyID.
-        * 
-        * @param this                                  calling object
-        * @param keyid                                 identification_t object identifiying the cacert.
-        * @return                                              certificate, or NULL if not found
-        */
-       x509_t* (*get_ca_certificate_by_keyid) (credential_store_t *this, chunk_t keyid);
-       
-       /**
-        * @brief Returns the issuing ca of a given certificate.
-        * 
-        * @param this                                  calling object
-        * @param cert                                  certificate for which issuer ca info is required
-        * @return                                              ca info, or NULL if not found
-        */
-       ca_info_t* (*get_issuer) (credential_store_t *this, x509_t* cert);
-
-       /**
-        * @brief  RSA private key belonging to an RSA public key
-        * 
-        * 
-        * @param this                                  calling object
-        * @param pubkey                                public key used to find the matching private key
-        * @param hash_algorithm                hash algorithm to be used for signature
-        * @param data                                  data block to be signed
-        * @param signature                             signature to be returned
-        * @return                                              status of the signature process - SUCCESS if successful
-        */     
-       status_t (*rsa_signature) (credential_store_t *this, rsa_public_key_t *pubkey, hash_algorithm_t hash_algorithm,
-                                                          chunk_t data, chunk_t *signature);
-
-       /**
-        * @brief Verify an RSA signature given the ID of the signer
-        * 
-        * @param this                                  calling object
-        * @param hash                                  hash value to be verified.
-        * @param sig                                   signature to be verified.
-        * @param id                                    identification_t object identifiying the signer.
-        * @param issuer_p                              issuer of the signer's certificate (if not self-signed).
-        * @return                                              status of the verification - SUCCESS if successful
-        */
-       status_t (*verify_signature) (credential_store_t *this, chunk_t hash, chunk_t sig, identification_t *id,
-                                                                 ca_info_t **issuer_p);
-       
-       /**
-        * @brief Verify an X.509 certificate up to trust anchor without any status checks
-        *
-        * @param this          calling object
-        * @param label         label characterizing the certificate to be verified
-        * @param cert          certificate to be verified
-        * @return                      TRUE if trusted
-        */
-       bool (*is_trusted) (credential_store_t *this, const char *label, x509_t *cert);
-
-       /**
-        * @brief Verify an X.509 certificate up to trust anchor including status checks
-        *
-        * @param this          calling object
-        * @param cert          certificate to be verified
-        * @param found         found a certificate copy in the credential store
-        * @return                      TRUE if valid, trusted, and current status is good
-        */
-       bool (*verify) (credential_store_t *this, x509_t *cert, bool *found);
-
-       /**
-        * @brief If an end certificate does not already exists in the credential store then add it.
-        *
-        * @param this          calling object
-        * @param cert          certificate to be added
-        * @return                      pointer to the added or already existing certificate
-        */
-       x509_t* (*add_end_certificate) (credential_store_t *this, x509_t *cert);
-
-       /**
-        * @brief If an authority certificate does not already exists in the credential store then add it.
-        *
-        * @param this                  calling object
-        * @param cert                  authority certificate to be added
-        * @param auth_flag             authority flags to add to the certificate
-        * @return                              pointer to the added or already existing certificate
-        */
-       x509_t* (*add_auth_certificate) (credential_store_t *this, x509_t *cert, u_int auth_flag);
-
-       /**
-        * @brief If a ca info record does not already exists in the credential store then add it.
-        *
-        * @param this          calling object
-        * @param ca_info       ca info record to be added
-        * @return                      pointer to the added or already existing ca_info_t record
-        */
-       ca_info_t* (*add_ca_info) (credential_store_t *this, ca_info_t *ca_info);
-
-       /**
-        * @brief Release a ca info record with a given name.
-        *
-        * @param this          calling object
-        * @param name          name of the ca info record to be released
-        * @return
-        *                                                      - SUCCESS, or
-        *                                                      - NOT_FOUND
-        */
-       status_t (*release_ca_info) (credential_store_t *this, const char *name);
-
-       /**
-        * @brief Create an iterator over all end certificates.
-        *
-        * @param this          calling object
-        * @return                      iterator
-        */
-       iterator_t* (*create_cert_iterator) (credential_store_t *this);
-
-       /**
-        * @brief Create an iterator over all authority certificates.
-        *
-        * @param this          calling object
-        * @return                      iterator
-        */
-       iterator_t* (*create_auth_cert_iterator) (credential_store_t *this);
-
-       /**
-        * @brief Create an iterator over all CA info records
-        *
-        * @param this          calling object
-        * @return                      iterator
-        */
-       iterator_t* (*create_cainfo_iterator) (credential_store_t *this);
-
-       /**
-        * @brief Create an iterator over all attribute certificates.
-        *
-        * @param this          calling object
-        * @return                      iterator
-        */
-       iterator_t* (*create_acert_iterator) (credential_store_t *this);
-
-       /**
-        * @brief Loads ca certificates from a default directory.
-        *
-        * Certificates in both DER and PEM format are accepted
-        *
-        * @param this          calling object
-        */
-       void (*load_ca_certificates) (credential_store_t *this);
-       
-       /**
-        * @brief Loads authorization authority certificates from a default directory.
-        *
-        * Certificates in both DER and PEM format are accepted
-        *
-        * @param this          calling object
-        */
-       void (*load_aa_certificates) (credential_store_t *this);
-
-       /**
-        * @brief Loads attribute certificates from a default directory.
-        *
-        * Certificates in both DER and PEM format are accepted
-        *
-        * @param this          calling object
-        */
-       void (*load_attr_certificates) (credential_store_t *this);
-
-       /**
-        * @brief Loads ocsp certificates from a default directory.
-        *
-        * Certificates in both DER and PEM format are accepted
-        *
-        * @param this          calling object
-        */
-       void (*load_ocsp_certificates) (credential_store_t *this);
-       
-       /**
-        * @brief Loads CRLs from a default directory.
-        *
-        * Certificates in both DER and PEM format are accepted
-        *
-        * @param this          calling object
-        * @param path          directory to load crls from 
-        */
-       void (*load_crls) (credential_store_t *this);
-       
-       /**
-        * @brief Loads secrets in ipsec.secrets
-        * 
-        * RSA private key files can be either in DER or PEM format
-     * Optional encryption with a passphrase supported
-        * 
-        * @param this          calling object
-        * @param reload        are the secrets to be reloaded
-        */
-       void (*load_secrets) (credential_store_t *this, bool reload);
-
-       /**
-        * @brief Destroys a credential_store_t object.
-        * 
-        * @param this          calling object
-        */
-       void (*destroy) (credential_store_t *this);
-};
-
-/**
- * @brief Creates a credential_store_t instance.
- *
- * @param  strict              enforce a strict crl policy
- * @return                             credential store instance.
- * 
- * @ingroup config
- */
-credential_store_t *credential_store_create(bool strict);
-
-
-#endif /*CREDENTIAL_STORE_H_*/
diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c
new file mode 100644 (file)
index 0000000..c4c3ba1
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 "builder.h"
+
+ENUM(builder_part_names, BUILD_BLOB_ASN1_DER, BUILD_END,
+       "BUILD_BLOB_ASN1_DER",
+       "BUILD_KEY_SIZE",
+       "BUILD_SIGNING_KEY",
+       "BUILD_SIGNING_CERT",
+       "BUILD_PUBLIC_KEY",
+       "BUILD_SUBJECT",
+       "BUILD_SUBJECT_ALTNAME",
+       "BUILD_ISSUER",
+       "BUILD_ISSUER_ALTNAME",
+       "BUILD_CA_CERT",
+       "BUILD_CERT",
+       "BUILD_END",
+);
diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h
new file mode 100644 (file)
index 0000000..14c3d24
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup builder builder
+ * @{ @ingroup credentials
+ */
+
+#ifndef BUILDER_H_
+#define BUILDER_H_
+
+typedef struct builder_t builder_t;
+typedef enum builder_part_t builder_part_t;
+
+/**
+ * Constructor function which creates a new builder instance.
+ *
+ * @param subtype      constructor specific subtype, e.g. certificate_type_t
+ * @return                     builder to construct a instance of type
+ */
+typedef builder_t* (*builder_constructor_t)(int subtype);
+
+#include <library.h>
+
+/**
+ * Parts to build credentials from.
+ */
+enum builder_part_t {
+       /** DER encoded ASN1 blob, argument is a chunk_t */
+       BUILD_BLOB_ASN1_DER,
+       /** key size in bits, as used for key generation, as u_int */
+       BUILD_KEY_SIZE,
+       /** private key to use for signing, private_key_t* */
+       BUILD_SIGNING_KEY,
+       /** certificate used for signing, certificate_t* */
+       BUILD_SIGNING_CERT,
+       /** public key to include, public_key_t* */
+       BUILD_PUBLIC_KEY,
+       /** subject for e.g. certificates, identification_t* */
+       BUILD_SUBJECT,
+       /** additional subject name, identification_t* */
+       BUILD_SUBJECT_ALTNAME,
+       /** issuer for e.g. certificates, identification_t* */
+       BUILD_ISSUER,
+       /** additional issuer name, identification_t* */
+       BUILD_ISSUER_ALTNAME,
+       /** a CA certificate, certificate_t* */
+       BUILD_CA_CERT,
+       /** a certificcate, certificate_t* */
+       BUILD_CERT,
+       /** end of variable argument builder list */
+       BUILD_END,
+};
+
+/**
+ * enum names for build_part_t
+ */
+extern enum_name_t *builder_part_names;
+
+/**
+ * Credential construction API.
+ *
+ * The builder allows the construction of credentials in a generic and
+ * flexible way.
+ */
+struct builder_t {
+
+       /**
+        * Add a part to the construct.
+        *
+        * Any added parts get owned by the builder/construct, so clone/refcount
+        * them if needed.
+        *
+        * @param part          kind of part
+        * @param ...           part specific variable argument
+        */
+       void (*add)(builder_t *this, builder_part_t part, ...);
+       
+       /**
+        * Build the construct with all supplied parts.
+        *
+        * Once build() is called, the builder gets destroyed.
+        *
+        * @return                      specific interface, as requested with constructor.
+        */
+       void* (*build)(builder_t *this);
+};
+
+#endif /* BUILDER_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/certificate.c b/src/libstrongswan/credentials/certificates/certificate.c
new file mode 100644 (file)
index 0000000..649ab30
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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$
+ */
+
+#include "certificate.h"
+
+#include <credentials/certificates/x509.h>
+
+ENUM(certificate_type_names, CERT_ANY, CERT_PGP,
+       "ANY",
+       "X509",
+       "X509_CRL",
+       "X509_OCSP_REQUEST",
+       "X509_OCSP_RESPONSE",
+       "X509_AC",
+       "X509_CHAIN",
+       "TRUSTED_PUBKEY",
+       "PGP",
+);
+
+ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_SKIPPED,
+       "GOOD",
+       "REVOKED",
+       "FAILED",
+       "SKIPPED",
+);
+
diff --git a/src/libstrongswan/credentials/certificates/certificate.h b/src/libstrongswan/credentials/certificates/certificate.h
new file mode 100644 (file)
index 0000000..94f19a0
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2007-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup certificate certificate
+ * @{ @ingroup certificates
+ */
+
+#ifndef CERTIFICATE_H_
+#define CERTIFICATE_H_
+
+typedef struct certificate_t certificate_t;
+typedef enum certificate_type_t certificate_type_t;
+typedef enum cert_validation_t cert_validation_t;
+
+#include <library.h>
+#include <utils/identification.h>
+#include <credentials/keys/public_key.h>
+
+/**
+ * Kind of a certificate_t
+ */
+enum certificate_type_t {
+       /** just any certificate */
+       CERT_ANY,
+       /** X.509 certificate */
+       CERT_X509,
+       /** X.509 certificate revocation list */
+       CERT_X509_CRL,
+       /** X.509 online certificate status protocol request */
+       CERT_X509_OCSP_REQUEST,
+       /** X.509 online certificate status protocol response */
+       CERT_X509_OCSP_RESPONSE,
+       /** X.509 attribute certificate */
+       CERT_X509_AC,
+       /** trusted, preinstalled public key */
+       CERT_TRUSTED_PUBKEY,
+       /** PGP certificate */
+       CERT_PGP,
+};
+
+/**
+ * Enum names for certificate_type_t
+ */
+extern enum_name_t *certificate_type_names;
+
+/**
+ * Result of a certificate validation.
+ */
+enum cert_validation_t {
+       /** certificate has been validated successfully */
+       VALIDATION_GOOD,
+       /** validation failed, certificate is revoked */
+       VALIDATION_REVOKED,
+       /* ocsp status is unknown or crl is stale */
+       VALIDATION_UNKNOWN,
+       /** validation process failed due to an error */
+       VALIDATION_FAILED,
+       /** validation has been skipped (no cdps available) */
+       VALIDATION_SKIPPED,
+};
+
+/**
+ * Enum names for cert_validation_t
+ */
+extern enum_name_t *cert_validation_names;
+
+/**
+ * An abstract certificate.
+ *
+ * A certificate designs a subject-issuer relationship. It may have an 
+ * associated public key.
+ */
+struct certificate_t {
+
+       /**
+        * Get the type of the certificate.
+        *
+        * @return                      certifcate type
+        */
+       certificate_type_t (*get_type)(certificate_t *this);
+
+       /**
+        * Get the primary subject to which this certificate belongs.
+        *
+        * @return                      subject identity
+        */
+       identification_t* (*get_subject)(certificate_t *this);
+       
+       /**
+        * Check if certificate contains a subject ID.
+        *
+        * A certificate may contain additional subject identifiers, which are
+        * not returned by get_subject (e.g. subjectAltNames)
+        *
+        * @param subject       subject identity
+        * @return                      matching value of best match
+        */
+       id_match_t (*has_subject)(certificate_t *this, identification_t *subject);
+               
+       /**
+        * Get the issuer which signed this certificate.
+        *
+        * @return                      issuer identity
+        */
+       identification_t* (*get_issuer)(certificate_t *this);
+       
+       /**
+        * Check if certificate contains an issuer ID.
+        *
+        * A certificate may contain additional issuer identifiers, which are
+        * not returned by get_issuer (e.g. issuerAltNames)
+        *
+        * @param subject       isser identity
+        * @return                      matching value of best match
+        */
+       id_match_t (*has_issuer)(certificate_t *this, identification_t *issuer);
+       
+       /**
+        * Check if this certificate is issued by a specific issuer.
+        *
+        * As signature verification is computional expensive, it is optional 
+        * and may be skipped. While this is not sufficient for verification
+        * purposes, it is to e.g. find matching certificates.
+        * 
+        * @param issuer        issuer's certificate
+        * @param checksig      TRUE to verify signature, FALSE to compare issuer only
+        * @return                      TRUE if certificate issued by issuer and trusted
+        */
+       bool (*issued_by)(certificate_t *this, certificate_t *issuer, bool checksig);
+       
+       /**
+        * Get the public key associated to this certificate.
+        *
+        * @return                      newly referenced public_key, NULL if none available
+        */
+       public_key_t* (*get_public_key)(certificate_t *this);
+       
+       /**
+        * Check the lifetime of the certificate.
+        *
+        * @param when                  check validity at a certain time (NULL for now)
+        * @param not_before    receives certificates start of lifetime
+        * @param not_after             receives certificates end of lifetime
+        * @return                              TRUE if when between not_after and not_before
+        */
+       bool (*get_validity)(certificate_t *this, time_t *when,
+                                                time_t *not_before, time_t *not_after);
+       
+       /**
+        * Get the certificate in an encoded form.
+        *
+        * @return                              allocated chunk of encoded cert
+        */
+       chunk_t (*get_encoding)(certificate_t *this);
+       
+       /**
+        * Check if two certificates are equal.
+        *
+        * @param other                 certificate to compair against this
+        * @return                              TRUE if certificates are equal
+        */
+       bool (*equals)(certificate_t *this, certificate_t *other);
+       
+       /**
+        * Get a new reference to the certificate.
+        *
+        * @return                      this, with an increased refcount 
+        */
+       certificate_t* (*get_ref)(certificate_t *this);
+       
+       /**
+     * Destroy a certificate.
+     */
+    void (*destroy)(certificate_t *this);
+};
+
+#endif /* CERTIFICATE_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/crl.c b/src/libstrongswan/credentials/certificates/crl.c
new file mode 100644 (file)
index 0000000..48fb24a
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2006 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.
+ *
+ * $Id$
+ */
+
+#include "crl.h"
+
+ENUM(crl_reason_names, CRL_UNSPECIFIED, CRL_REMOVE_FROM_CRL,
+       "unspecified",
+       "key compromise",
+       "ca compromise",
+       "affiliation changed",
+       "superseded",
+       "cessation of operation",
+       "certificate hold",
+       "reason #7",
+       "remove from crl",
+);
+
diff --git a/src/libstrongswan/credentials/certificates/crl.h b/src/libstrongswan/credentials/certificates/crl.h
new file mode 100644 (file)
index 0000000..752293f
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2006 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 crl crl
+ * @{ @ingroup certificates
+ */
+
+#ifndef CRL_H_
+#define CRL_H_
+
+typedef struct crl_t crl_t;
+typedef enum crl_reason_t crl_reason_t;
+
+#include <library.h>
+#include <utils/linked_list.h>
+
+/**
+ * RFC 2459 CRL reason codes
+ */
+enum crl_reason_t {
+    CRL_UNSPECIFIED                    = 0,
+    CRL_KEY_COMPROMISE                 = 1,
+    CRL_CA_COMPROMISE                  = 2,
+    CRL_AFFILIATION_CHANGED            = 3,
+    CRL_SUPERSEDED                             = 4,
+    CRL_CESSATION_OF_OPERATON  = 5,
+    CRL_CERTIFICATE_HOLD               = 6,
+    CRL_REMOVE_FROM_CRL                        = 8,
+};
+
+/**
+ * enum names for crl_reason_t
+ */
+extern enum_name_t *crl_reason_names;
+
+/**
+ * X509 certificate revocation list (CRL) interface definition.
+ */
+struct crl_t {
+
+       /**
+        * Implements (parts of) the certificate_t interface
+        */
+       certificate_t certificate;
+       
+       /**
+        * Is that newer than this?
+        *
+        * @return                      TRUE if newer, FALSE otherwise
+        */
+       bool (*is_newer)(crl_t *this, crl_t *that);
+       
+       /**
+        * Get the CRL serial number.
+        *
+        * @return                      chunk pointing to internal crlNumber
+        */
+       chunk_t (*get_serial)(crl_t *this);
+       
+       /**
+        * Get the the authorityKeyIdentifier.
+        *
+        * @return                      authKeyIdentifier as identification_t*
+        */
+       identification_t* (*get_authKeyIdentifier)(crl_t *this);
+       
+       /**
+        * Create an enumerator over all revoked certificates.
+        *
+        * The enumerator takes 3 pointer arguments:
+        * chunk_t serial, time_t revocation_date, crl_reason_t reason
+        *
+        * @return                      enumerator over revoked certificates.
+        */
+       enumerator_t* (*create_enumerator)(crl_t *this);
+       
+};
+
+#endif /* CRL_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/ocsp_request.c b/src/libstrongswan/credentials/certificates/ocsp_request.c
new file mode 100644 (file)
index 0000000..0958be4
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "ocsp_request.h"
+
diff --git a/src/libstrongswan/credentials/certificates/ocsp_request.h b/src/libstrongswan/credentials/certificates/ocsp_request.h
new file mode 100644 (file)
index 0000000..377eabd
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup ocsp_request ocsp_request
+ * @{ @ingroup certificates
+ */
+
+#ifndef OCSP_REQUEST_H_
+#define OCSP_REQUEST_H_
+
+#include <credentials/certificates/certificate.h>
+
+typedef struct ocsp_request_t ocsp_request_t;
+
+/**
+ * OCSP request message.
+ */
+struct ocsp_request_t {
+
+       /**
+        * Implements certificiate_t interface
+        */
+       certificate_t interface;
+};
+
+#endif /* OCSP_REQUEST_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.c b/src/libstrongswan/credentials/certificates/ocsp_response.c
new file mode 100644 (file)
index 0000000..02e12f7
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "ocsp_response.h"
+
+ENUM(ocsp_status_names, OCSP_SUCCESSFUL, OCSP_UNAUTHORIZED,
+       "successful",
+       "malformed request",
+       "internal error",
+       "try later",
+       "status #4",
+       "signature required",
+       "unauthorized"
+);
+
diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.h b/src/libstrongswan/credentials/certificates/ocsp_response.h
new file mode 100644 (file)
index 0000000..416f712
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup ocsp_response ocsp_response
+ * @{ @ingroup certificates
+ */
+
+#ifndef OCSP_RESPONSE_H_
+#define OCSP_RESPONSE_H_
+
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+
+typedef struct ocsp_response_t ocsp_response_t;
+typedef enum ocsp_status_t ocsp_status_t;
+
+/**
+ * OCSP response status 
+ */
+enum ocsp_status_t {
+       OCSP_SUCCESSFUL                 = 0,
+       OCSP_MALFORMEDREQUEST   = 1,
+       OCSP_INTERNALERROR              = 2,
+       OCSP_TRYLATER                   = 3,
+       OCSP_SIGREQUIRED                = 5,
+       OCSP_UNAUTHORIZED               = 6,
+};
+
+/**
+ * enum names for ocsp_status_t
+ */
+extern enum_name_t *ocsp_status_names;
+
+/**
+ * OCSP response message.
+ */
+struct ocsp_response_t {
+
+       /**
+        * Implements certificiate_t interface
+        */
+       certificate_t certificate;
+       
+       /**
+        * Check the status of a certificate by this OCSP response.
+        *
+        * @param subject                       certificate to check status
+        * @param issuer                        issuer certificate of subject
+        * @param revocation_time       receives time of revocation, if revoked
+        * @param revocation_reason     receives reason of revocation, if revoked
+        * @param this_update           creation time of revocation list
+        * @param next_update           exptected time of next revocation list
+        * @return                                      certificate revocation status
+        */
+       cert_validation_t (*get_status)(ocsp_response_t *this, 
+                                                                       x509_t *subject, x509_t *issuer,
+                                                                       time_t *revocation_time,
+                                                                       crl_reason_t *revocation_reason,
+                                                                       time_t *this_update, time_t *next_update);
+       
+       /**
+        * Create an enumerator over the contained certificates.
+        *
+        * @return                                      enumerator over certificate_t*
+        */
+       enumerator_t* (*create_cert_enumerator)(ocsp_response_t *this); 
+};
+
+#endif /* OCSP_RESPONSE_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/x509.c b/src/libstrongswan/credentials/certificates/x509.c
new file mode 100644 (file)
index 0000000..a5f4fc1
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "x509.h"
+
+ENUM(x509_flag_names, X509_CA, X509_SELF_SIGNED,
+       "X509_CA",
+       "X509_AA",
+       "X509_OCSP_SIGNER",
+       "X509_SELF_SIGNED",
+);
diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h
new file mode 100644 (file)
index 0000000..a4f9d1f
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2007-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup x509 x509
+ * @{ @ingroup certificates
+ */
+
+#ifndef X509_H_
+#define X509_H_
+
+#include <utils/enumerator.h>
+#include <credentials/certificates/certificate.h>
+
+typedef struct x509_t x509_t;
+typedef enum x509_flag_t x509_flag_t;
+
+/**
+ * X.509 certificate flags.
+ */
+enum x509_flag_t {
+       /** cert has CA constraint */
+       X509_CA =                       (1<<0),
+       /** cert has AA constraint */
+       X509_AA =                       (1<<1),
+       /** cert has OCSP signer constraint */
+       X509_OCSP_SIGNER =      (1<<2),
+       /** cert belongs to an end entity  */
+       X509_PEER =         (1<<3),
+       /** cert is self-signed */
+       X509_SELF_SIGNED =  (1<<4),
+};
+
+/**
+ * enum names for x509 flags
+ */
+extern enum_name_t *x509_flag_names;
+
+/**
+ * X.509 certificate interface.
+ *
+ * This interface adds additional methods to the certificate_t type to
+ * allow further operations on these certificates.
+ */
+struct x509_t {
+
+       /**
+        * Implements certificate_t.
+        */
+       certificate_t interface;
+       
+       /**
+        * Get the flags set for this certificate.
+        *
+        * @return                      set of flags
+        */
+       x509_flag_t (*get_flags)(x509_t *this);
+       
+       /**
+        * Set the flags for this certificate.
+        *
+        * @param flags         set of flags
+        */
+       void (*set_flags)(x509_t *this, x509_flag_t flags);
+       
+       /**
+        * Get the certificate serial number.
+        *
+        * @return                      chunk pointing to internal serial number
+        */
+       chunk_t (*get_serial)(x509_t *this);
+       
+       /**
+        * Get the the authorityKeyIdentifier.
+        *
+        * @return                      authKeyIdentifier as identification_t*
+        */
+       identification_t* (*get_authKeyIdentifier)(x509_t *this);
+       
+       /**
+        * Create an enumerator over all subjectAltNames.
+        *
+        * @return                      enumerator over subjectAltNames as identification_t*
+        */
+       enumerator_t* (*create_subjectAltName_enumerator)(x509_t *this);
+       
+       /**
+        * Create an enumerator over all CRL URIs.
+        *
+        * @return                      enumerator over URIs as char*
+        */
+       enumerator_t* (*create_crl_uri_enumerator)(x509_t *this);
+       
+       /**
+        * Create an enumerator over all OCSP URIs.
+        *
+        * @return                      enumerator over URIs as char*
+        */
+       enumerator_t* (*create_ocsp_uri_enumerator)(x509_t *this);
+};
+
+#endif /* X509_H_ @}*/
diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c
new file mode 100644 (file)
index 0000000..ab99a42
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "credential_factory.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+typedef struct private_credential_factory_t private_credential_factory_t;
+
+/**
+ * private data of credential_factory
+ */
+struct private_credential_factory_t {
+
+       /**
+        * public functions
+        */
+       credential_factory_t public;
+       
+       /**
+        * list with entry_t
+        */
+       linked_list_t *constructors;
+       
+       /**
+        * mutex to lock access to modules
+        */
+       mutex_t *mutex;
+};
+
+typedef struct entry_t entry_t;
+struct entry_t {
+       /** kind of credential builder */
+       credential_type_t type;
+       /** subtype of credential, e.g. certificate_type_t */
+       int subtype;
+       /** builder construction function */
+       builder_constructor_t constructor;
+};
+
+/**
+ * Implementation of credential_factory_t.create_builder.
+ */
+static builder_t* create_builder(private_credential_factory_t *this,
+                                                                credential_type_t type, int subtype)
+{
+       enumerator_t *enumerator;
+       entry_t *entry;
+       builder_t *builder = NULL;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->constructors->create_enumerator(this->constructors);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->type == type && entry->subtype == subtype)
+               {
+                       builder = entry->constructor(subtype);
+                       if (builder)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return builder;
+}
+
+/**
+ * Implementation of credential_factory_t.add_builder_constructor.
+ */
+static void add_builder(private_credential_factory_t *this,
+                                               credential_type_t type, int subtype,
+                                               builder_constructor_t constructor)
+{
+       entry_t *entry = malloc_thing(entry_t);
+       
+       entry->type = type;
+       entry->subtype = subtype;
+       entry->constructor = constructor;
+       this->mutex->lock(this->mutex);
+       this->constructors->insert_last(this->constructors, entry);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of credential_factory_t.remove_builder.
+ */
+static void remove_builder(private_credential_factory_t *this,
+                                                  builder_constructor_t constructor)
+{
+       enumerator_t *enumerator;
+       entry_t *entry;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->constructors->create_enumerator(this->constructors);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->constructor == constructor)
+               {
+                       this->constructors->remove_at(this->constructors, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of credential_factory_t.create.
+ */
+static void* create(private_credential_factory_t *this, credential_type_t type,
+                                       int subtype, ...)
+{
+       builder_t *builder;
+       builder_part_t part;
+       va_list args;
+       
+       builder = create_builder(this, type, subtype);
+       if (builder)
+       {
+               va_start(args, subtype);
+               while (TRUE)
+               {
+                       part = va_arg(args, builder_part_t);
+               
+                       switch (part)
+                       {
+                               case BUILD_END:
+                                       break;
+                               case BUILD_BLOB_ASN1_DER:
+                                       builder->add(builder, part, va_arg(args, chunk_t));
+                                       continue;
+                               case BUILD_KEY_SIZE:
+                                       builder->add(builder, part, va_arg(args, u_int));
+                                       continue;
+                               case BUILD_SIGNING_KEY:
+                               case BUILD_PUBLIC_KEY:
+                               case BUILD_SUBJECT:
+                               case BUILD_SUBJECT_ALTNAME:
+                               case BUILD_ISSUER:
+                               case BUILD_ISSUER_ALTNAME:
+                               case BUILD_SIGNING_CERT:
+                               case BUILD_CA_CERT:
+                               case BUILD_CERT:
+                                       builder->add(builder, part, va_arg(args, void*));
+                                       continue;
+                               default:
+                                       DBG1("builder part %N not supported by factory",
+                                                builder_part_names, part);
+                                       continue;
+                       }
+                       break;
+               }
+               va_end(args);
+       
+               return builder->build(builder);
+       }
+       
+       /** shredder all data on failure */
+       va_start(args, subtype);
+       while (TRUE)
+       {
+               part = va_arg(args, builder_part_t);
+               
+               switch (part)
+               {
+                       case BUILD_END:
+                               break;
+                       case BUILD_BLOB_ASN1_DER:
+                       {
+                               chunk_t chunk = va_arg(args, chunk_t);
+                               free(chunk.ptr);
+                               continue;
+                       }
+                       case BUILD_SIGNING_KEY:
+                       {
+                               private_key_t *private = va_arg(args, private_key_t*);
+                               private->destroy(private);
+                               continue;
+                       }
+                       case BUILD_PUBLIC_KEY:
+                       {
+                               public_key_t *public = va_arg(args, public_key_t*);
+                               public->destroy(public);
+                               continue;
+                       }
+                       case BUILD_SUBJECT:
+                       case BUILD_SUBJECT_ALTNAME:
+                       case BUILD_ISSUER:
+                       case BUILD_ISSUER_ALTNAME:
+                       {
+                               identification_t *id = va_arg(args, identification_t*);
+                               id->destroy(id);
+                               continue;
+                       }
+                       case BUILD_SIGNING_CERT:
+                       case BUILD_CA_CERT:
+                       case BUILD_CERT:
+                       {
+                               certificate_t *cert = va_arg(args, certificate_t*);
+                               cert->destroy(cert);
+                               continue;
+                       }
+                       case BUILD_KEY_SIZE:
+                               continue;
+                       default:
+                               DBG1("builder part %N not supported by factory",
+                                        builder_part_names, part);
+                               continue;
+               }
+               break;
+       }
+       va_end(args);
+       return NULL;
+}
+
+/**
+ * Implementation of credential_factory_t.destroy
+ */
+static void destroy(private_credential_factory_t *this)
+{
+       this->constructors->destroy_function(this->constructors, free);
+       this->mutex->destroy(this->mutex);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+credential_factory_t *credential_factory_create()
+{
+       private_credential_factory_t *this = malloc_thing(private_credential_factory_t);
+
+       this->public.create = (void*(*)(credential_factory_t*, credential_type_t type, int subtype, ...))create;
+       this->public.create_builder = (builder_t*(*)(credential_factory_t*, credential_type_t type, int subtype))create_builder;
+       this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_constructor_t constructor))add_builder;
+       this->public.remove_builder = (void(*)(credential_factory_t*,builder_constructor_t constructor))remove_builder;
+       this->public.destroy = (void(*)(credential_factory_t*))destroy;
+       
+       this->constructors = linked_list_create();
+       
+       this->mutex = mutex_create(MUTEX_RECURSIVE);
+       
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/credentials/credential_factory.h b/src/libstrongswan/credentials/credential_factory.h
new file mode 100644 (file)
index 0000000..394d0b0
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup credential_factory credential_factory
+ * @{ @ingroup credentials
+ */
+
+#ifndef CREDENTIAL_FACTORY_H_
+#define CREDENTIAL_FACTORY_H_
+
+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>
+
+/**
+ * Kind of credential.
+ */
+enum credential_type_t {
+       /** private key, implemented in private_key_t */
+       CRED_PRIVATE_KEY,
+       /** public key, implemented in public_key_t */
+       CRED_PUBLIC_KEY,
+       /** certificates, implemented in certificate_t */
+       CRED_CERTIFICATE,
+};
+
+/**
+ * Manages credential construction functions and creates instances.
+ */
+struct credential_factory_t {
+                                                
+       /**
+        * Create a credential using a list of builder_part_t's.
+        *
+        * The variable argument list takes builder_part_t types followed
+        * by the type specific value. The list must be terminated using BUILD_END.
+        *
+        * @param type                  credential type to build
+        * @param subtype               subtype specific for type of the credential
+        * @param ...                   build_part_t arguments, BUILD_END terminated.
+        * @return                              type specific credential, NULL if failed
+        */
+       void* (*create)(credential_factory_t *this, credential_type_t type,
+                                       int subtype, ...);
+       
+       /**
+        * Create a builder instance to build credentials.
+        *
+        * @param type                  type of credentials the builder creates
+        * @param subtype               type specific subtype, such as certificate_type_t
+        * @return                              builder instance
+        */
+       builder_t* (*create_builder)(credential_factory_t *this,
+                                                                credential_type_t type, int subtype);
+       /**
+        * Register a builder_t constructor function.
+        *
+        * @param type                  type of credential the builder creates
+        * @param constructor   builder constructor function to register
+        */
+       void (*add_builder)(credential_factory_t *this,
+                                               credential_type_t type, int subtype, 
+                                               builder_constructor_t constructor);
+       /**
+        * Unregister a builder_t constructor function.
+        *
+        * @param constructor   constructor function to unregister.
+        */
+       void (*remove_builder)(credential_factory_t *this, 
+                                                  builder_constructor_t constructor);
+       
+       /**
+     * Destroy a credential_factory instance.
+     */
+    void (*destroy)(credential_factory_t *this);
+};
+
+/**
+ * Create a credential_factory instance.
+ */
+credential_factory_t *credential_factory_create();
+
+#endif /* CREDENTIAL_FACTORY_H_ @}*/
diff --git a/src/libstrongswan/credentials/keys/private_key.c b/src/libstrongswan/credentials/keys/private_key.c
new file mode 100644 (file)
index 0000000..9853bda
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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$
+ */
+
+#include "private_key.h"
+
diff --git a/src/libstrongswan/credentials/keys/private_key.h b/src/libstrongswan/credentials/keys/private_key.h
new file mode 100644 (file)
index 0000000..fbb5abf
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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$
+ */
+/**
+ * @defgroup private_key private_key
+ * @{ @ingroup keys
+ */
+
+#ifndef PRIVATE_KEY_H_
+#define PRIVATE_KEY_H_
+
+typedef struct private_key_t private_key_t;
+
+#include <utils/identification.h>
+#include <credentials/keys/public_key.h>
+
+/**
+ * Abstract private key interface.
+ */
+struct private_key_t {
+
+       /**
+        * Get the key type.
+        *
+        * @return                      type of the key
+        */
+       key_type_t (*get_type)(private_key_t *this);
+
+       /**
+        * Create a signature over a chunk of data.
+        *
+        * @param scheme        signature scheme to use
+        * @param data          chunk of data to sign
+        * @param signature     where to allocate created signature
+        * @return                      TRUE if signature created
+        */
+       bool (*sign)(private_key_t *this, signature_scheme_t scheme, 
+                                chunk_t data, chunk_t *signature);
+       /**
+        * Decrypt a chunk of data.
+        *
+        * @param crypto        chunk containing encrypted data
+        * @param plain         where to allocate decrypted data
+        * @return                      TRUE if data decrypted and plaintext allocated
+        */
+       bool (*decrypt)(private_key_t *this, chunk_t crypto, chunk_t *plain);
+       
+       /**
+        * Get the strength of the key in bytes.
+        * 
+        * @return                      strength of the key in bytes
+        */
+       size_t (*get_keysize) (private_key_t *this);
+
+       /**
+        * Get a unique key identifier, such as a hash over the public key.
+        * 
+        * @param type          type of the key ID to get
+        * @return                      unique ID of the key as identification_t, or NULL
+        */
+       identification_t* (*get_id) (private_key_t *this, id_type_t type);
+       
+       /**
+        * Get the public part from the private key.
+        *
+        * @return                      public key
+        */
+       public_key_t* (*get_public_key)(private_key_t *this);
+       
+       /**
+        * Check if a private key belongs to a public key.
+        * 
+        * @param public        public key
+        * @return                      TRUE, if keys belong together
+        */
+       bool (*belongs_to) (private_key_t *this, public_key_t *public);
+       
+       /**
+        * Get an encoded form of the private key.
+        *
+        * @todo Do we need a encoding type specification?
+        *
+        * @return                      allocated chunk containing encoded private key
+        */
+       chunk_t (*get_encoding)(private_key_t *this);   
+       
+       /**
+        * Increase the refcount to this private key.
+        *
+        * @return                      this, with an increased refcount
+        */
+       private_key_t* (*get_ref)(private_key_t *this);
+               
+       /**
+     * Decrease refcount, destroy private_key if no more references.
+     */
+    void (*destroy)(private_key_t *this);
+};
+
+/**
+ * Read a private key from a file.
+ * 
+ * @param type                 type of the key
+ * @param filename             filename to read key from
+ * @param passphrase   passphrase to decrypt an encrypted key
+ * @return                             loaded private key, NULL if failed
+ */
+private_key_t *private_key_create_from_file(key_type_t type, char *filename,
+                                                                                   chunk_t passphrase);
+
+/**
+ * Create a private key from a chunk.
+ * 
+ * @param type                 type of the key
+ * @param chunk                        chunk to create key from
+ * @return                             loaded private key, NULL if failed
+ */
+private_key_t *private_key_create_from_chunk(key_type_t type, chunk_t chunk);
+
+/**
+ * Generate a new private key.
+ * 
+ * @param type                 type of the key
+ * @param size                 key size in bytes
+ * @return                             generated private key, NULL if failed
+ */
+private_key_t *private_key_create_generated(key_type_t type, size_t size);
+
+#endif /* PRIVATE_KEY_H_ @} */
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
new file mode 100644 (file)
index 0000000..654b53c
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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$
+ */
+
+#include "public_key.h"
+
+ENUM(key_type_names, KEY_RSA, KEY_RSA,
+       "RSA"
+);
+
+ENUM(signature_scheme_names, SIGN_DEFAULT, SIGN_RSA_EMSA_PKCS1_SHA512,
+       "DEFAULT",
+       "RSA_EMSA_PKCS1_MD5",
+       "RSA_EMSA_PKCS1_SHA1",
+       "RSA_EMSA_PKCS1_SHA256",
+       "RSA_EMSA_PKCS1_SHA384",
+       "RSA_EMSA_PKCS1_SHA512",
+);
+
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
new file mode 100644 (file)
index 0000000..2083db5
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * 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$
+ */
+/**
+ * @defgroup public_key public_key
+ * @{ @ingroup keys
+ */
+
+#ifndef PUBLIC_KEY_H_
+#define PUBLIC_KEY_H_
+
+typedef struct public_key_t public_key_t;
+typedef enum key_type_t key_type_t;
+typedef enum key_id_type_t key_id_type_t;
+typedef enum signature_scheme_t signature_scheme_t;
+
+#include <library.h>
+#include <utils/identification.h>
+
+/**
+ * Type of a key pair, the used crypto system
+ */
+enum key_type_t {
+       /** key type wildcard */
+       KEY_ANY,
+       /** RSA crypto system as in PKCS#1 */
+       KEY_RSA,
+       /** DSS, ElGamal, ECDSA, ... */
+};
+
+/**
+ * Enum names for key_type_t
+ */
+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.
+ */
+enum signature_scheme_t {
+       /** default scheme of that underlying crypto system */
+       SIGN_DEFAULT,
+       /** EMSA-PKCS1 with MD5  */
+       SIGN_RSA_EMSA_PKCS1_MD5,
+       /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA1 as hash.  */
+       SIGN_RSA_EMSA_PKCS1_SHA1,
+       /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA256 as hash. */
+       SIGN_RSA_EMSA_PKCS1_SHA256,     
+       /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA384 as hash. */
+       SIGN_RSA_EMSA_PKCS1_SHA384,     
+       /** EMSA-PKCS1 signature as in PKCS#1 standard using SHA512 as hash. */
+       SIGN_RSA_EMSA_PKCS1_SHA512,     
+};
+
+/**
+ * Enum names for signature_scheme_t
+ */
+extern enum_name_t *signature_scheme_names;
+
+/**
+ * Abstract interface of a public key.
+ */
+struct public_key_t {
+
+       /**
+        * Get the key type.
+        *
+        * @return                      type of the key
+        */
+       key_type_t (*get_type)(public_key_t *this);
+       
+       /**
+        * Verifies a signature against a chunk of data.
+        *
+        * @param scheme        signature scheme to use for verification, may be default
+        * @param data          data to check signature against
+        * @param signature     signature to check
+        * @return                      TRUE if signature matches
+        */
+       bool (*verify)(public_key_t *this, signature_scheme_t scheme, 
+                                  chunk_t data, chunk_t signature);
+       
+       /**
+        * Encrypt a chunk of data.
+        *
+        * @param crypto        chunk containing plaintext data
+        * @param plain         where to allocate encrypted data
+        * @return                      TRUE if data successfully encrypted
+        */
+       bool (*encrypt)(public_key_t *this, chunk_t crypto, chunk_t *plain);
+       
+       /**
+        * Get the strength of the key in bytes.
+        * 
+        * @return                      strength of the key in bytes
+        */
+       size_t (*get_keysize) (public_key_t *this);
+
+       /**
+        * Get a unique key identifier, such as a hash over the key.
+        * 
+        * @param type          type of the key ID to get
+        * @return                      unique ID of the key as identification_t, or NULL
+        */
+       identification_t* (*get_id) (public_key_t *this, id_type_t type);
+       
+       /**
+        * Get an encoded form of the key.
+        *
+        * @todo Do we need a encoding type specification?
+        *
+        * @return                      allocated chunk containing encoded key
+        */
+       chunk_t (*get_encoding)(public_key_t *this);    
+       
+       /**
+        * Increase the refcount of the key.
+        *
+        * @return                      this with an increased refcount
+        */
+       public_key_t* (*get_ref)(public_key_t *this);
+       
+       /**
+        * Destroy a public_key instance.
+        */
+       void (*destroy)(public_key_t *this);
+};
+
+/**
+ * Read a public key from a file.
+ * 
+ * @param type                 type of the key
+ * @param filename             filename to read key from
+ * @return                             loaded public key, NULL if failed
+ */
+public_key_t *public_key_create_from_file(key_type_t type, char *filename);
+
+/**
+ * Create a public key from a chunk.
+ * 
+ * @param type                 type of the key
+ * @param chunk                        chunk to create key from
+ * @return                             loaded public key, NULL if failed
+ */
+public_key_t *public_key_create_from_chunk(key_type_t type, chunk_t chunk);
+
+#endif /* PUBLIC_KEY_H_ @} */
diff --git a/src/libstrongswan/credentials/keys/shared_key.c b/src/libstrongswan/credentials/keys/shared_key.c
new file mode 100644 (file)
index 0000000..66b45a0
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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$
+ */
+
+#include "shared_key.h"
+
+ENUM(shared_key_type_names, SHARED_ANY, SHARED_PIN,
+       "ANY",
+       "IKE",
+       "EAP",
+       "PRIVATE_KEY_PASS",
+       "PIN",
+);
+
diff --git a/src/libstrongswan/credentials/keys/shared_key.h b/src/libstrongswan/credentials/keys/shared_key.h
new file mode 100644 (file)
index 0000000..86586a7
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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 shared_key shared_key
+ * @{ @ingroup keys
+ */
+
+#ifndef SHARED_KEY_H_
+#define SHARED_KEY_H_
+
+#include <utils/enumerator.h>
+#include <utils/identification.h>
+
+typedef struct shared_key_t shared_key_t;
+typedef enum shared_key_type_t shared_key_type_t;
+
+/**
+ * Type of a shared key.
+ */
+enum shared_key_type_t {
+       /** wildcard for all keys */
+       SHARED_ANY,
+       /** PSK for IKE authentication */
+       SHARED_IKE,
+       /** key for a EAP authentication method */
+       SHARED_EAP,
+       /** key to decrypt encrypted private keys */
+       SHARED_PRIVATE_KEY_PASS,
+       /** PIN to unlock a smartcard */
+       SHARED_PIN,
+};
+
+/**
+ * enum names for shared_key_type_t
+ */
+extern enum_name_t *shared_key_type_names;
+
+/**
+ * A symmetric key shared between multiple owners.
+ *
+ * This class is not thread save, do not add owners while others might be
+ * reading.
+ */
+struct shared_key_t {
+       
+       /**
+        * Get the kind of this key.
+        *
+        * @return                      type of the key
+        */
+       shared_key_type_t (*get_type)(shared_key_t *this);
+       
+       /**
+        * Get the shared key data.
+        *
+        * @return                      chunk pointing to the internal key
+        */
+       chunk_t (*get_key)(shared_key_t *this);
+       
+       /** 
+        * Increase refcount of the key.
+        *
+        * @return                      this with an increased refcount 
+        */
+       shared_key_t* (*get_ref)(shared_key_t *this);
+               
+       /**
+     * Destroy a shared_key instance if all references are gone.
+     */
+    void (*destroy)(shared_key_t *this);
+};
+
+#endif /** SHARED_KEY_H_ @} */
diff --git a/src/libstrongswan/crypto/ac.c b/src/libstrongswan/crypto/ac.c
deleted file mode 100644 (file)
index 3028212..0000000
+++ /dev/null
@@ -1,636 +0,0 @@
-/**
- * @file ac.c
- * 
- * @brief Implementation of x509ac_t.
- * 
- */
-
-/* 
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2007 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.
- *
- * RCSID $Id$
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <library.h>
-#include <debug.h>
-
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <crypto/x509.h>
-#include <crypto/ietf_attr_list.h>
-#include <utils/identification.h>
-#include <utils/linked_list.h>
-#include <utils/lexparser.h>
-
-#include "ac.h"
-
-#define ACERT_WARNING_INTERVAL 1       /* day */
-
-typedef struct private_x509ac_t private_x509ac_t;
-
-/**
- * Private data of a x509ac_t object.
- */
-struct private_x509ac_t {
-       /**
-        * Public interface for this attribute certificate.
-        */
-       x509ac_t public;
-
-       /**
-        * Time when attribute certificate was installed
-        */
-       time_t installed;
-
-       /**
-        * X.509 attribute certificate in DER format
-        */
-       chunk_t certificate;
-
-       /**
-        * X.509 attribute certificate body over which signature is computed
-        */
-       chunk_t certificateInfo;
-
-       /**
-        * Version of the X.509 attribute certificate
-        */
-       u_int version;
-
-       /**
-        * Serial number of the X.509 attribute certificate
-        */
-       chunk_t serialNumber;
-
-       /**
-        * ID representing the issuer of the holder certificate
-        */
-       identification_t *holderIssuer;
-
-       /**
-        * Serial number of the holder certificate
-        */
-       chunk_t holderSerial;
-
-       /**
-        * ID representing the holder
-        */
-       identification_t *entityName;
-       
-       /**
-        * ID representing the attribute certificate issuer
-        */
-       identification_t *issuerName;
-
-       /**
-        * Signature algorithm
-        */
-       int sigAlg;
-
-       /**
-        * Start time of certificate validity
-        */
-       time_t notBefore;
-
-       /**
-        * End time of certificate validity
-        */
-       time_t notAfter;
-
-       /**
-        * List of charging attributes
-        */
-       linked_list_t *charging;
-
-       /**
-        * List of groub attributes
-        */
-       linked_list_t *groups;
-
-       /**
-        * Authority Key Identifier
-        */
-       chunk_t authKeyID;
-
-       /**
-        * Authority Key Serial Number
-        */
-       chunk_t authKeySerialNumber;
-
-       /**
-        * No revocation information available
-        */
-       bool noRevAvail;
-
-       /**
-        * Signature algorithm (must be identical to sigAlg)
-        */
-       int algorithm;
-
-       /**
-        * Signature
-        */
-       chunk_t signature;
-};
-
-/**
- * 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 */
-};
-
-#define ROLE_ROOF              4
-
-/**
- * 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 */
-};
-
-#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
-
-/**
- * Implements x509ac_t.is_valid
- */
-static err_t is_valid(const private_x509ac_t *this, time_t *until)
-{
-       time_t current_time = time(NULL);
-       
-       DBG2("  not before  : %T", &this->notBefore);
-       DBG2("  current time: %T", &current_time);
-       DBG2("  not after   : %T", &this->notAfter);
-
-       if (until != NULL &&
-               (*until == UNDEFINED_TIME || this->notAfter < *until))
-       {
-               *until = this->notAfter;
-       }
-       if (current_time < this->notBefore)
-       {
-               return "is not valid yet";
-       }
-       if (current_time > this->notAfter)
-       {
-               return "has expired";
-       }
-       DBG2("  attribute certificate is valid");
-       return NULL;
-}
-
-/**
- * Implements x509ac_t.is_newer
- */
-static bool is_newer(const private_x509ac_t *this, const private_x509ac_t *other)
-{
-       return this->notBefore > other->notBefore;
-}
-
-/**
- * Implements x509ac_t.equals_holder.
- */
-static bool equals_holder(const private_x509ac_t *this, const private_x509ac_t *other)
-{
-       return this->holderIssuer->equals(this->holderIssuer, other->holderIssuer)
-                  && chunk_equals(this->holderSerial, other->holderSerial);
-}
-
-/**
- * parses a directoryName
- */
-static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
-{
-       bool has_directoryName;
-       linked_list_t *list = linked_list_create();
-
-       x509_parse_generalNames(blob, level, implicit, list);
-       has_directoryName = list->get_count(list) > 0;
-
-       if (has_directoryName)
-       {
-               iterator_t *iterator = list->create_iterator(list, TRUE);
-               identification_t *directoryName;
-               bool first = TRUE;
-
-               while (iterator->iterate(iterator, (void**)&directoryName))
-               {
-                       if (first)
-                       {
-                               *name = directoryName;
-                               first = FALSE;
-                       }
-                       else
-                       {
-                               DBG1("more than one directory name - first selected");
-                               directoryName->destroy(directoryName);
-                       }
-               }
-               iterator->destroy(iterator);
-       }
-       else
-       {
-               DBG1("no directoryName found");
-       }
-
-       list->destroy(list);
-       return has_directoryName;
-}
-
-/**
- * parses roleSyntax
- */
-static void parse_roleSyntax(chunk_t blob, int level0)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-       while (objectID < ROLE_ROOF)
-       {
-               if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
-               {
-                       return;
-               }
-
-               switch (objectID)
-               {
-                       default:
-                               break;
-               }
-               objectID++;
-       }
-}
-
-/**
- * Parses an X.509 attribute certificate
- */
-static bool parse_certificate(chunk_t blob, private_x509ac_t *this)
-{
-       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, FALSE);
-       while (objectID < AC_OBJ_ROOF)
-       {
-               if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
-               {
-                       return FALSE;
-               }
-
-               /* those objects which will parsed further need the next higher level */
-               level++;
-
-               switch (objectID)
-               {
-                       case AC_OBJ_CERTIFICATE:
-                               this->certificate = object;
-                               break;
-                       case AC_OBJ_CERTIFICATE_INFO:
-                               this->certificateInfo = object;
-                               break;
-                       case AC_OBJ_VERSION:
-                               this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
-                               DBG2("  v%d", this->version);
-                               if (this->version != 2)
-                               {
-                                       DBG1("v%d attribute certificates are not supported", this->version);
-                                       return FALSE;
-                               }
-                               break;
-                       case AC_OBJ_HOLDER_ISSUER:
-                               if (!parse_directoryName(object, level, FALSE, &this->holderIssuer))
-                               {
-                                       return FALSE;
-                               }
-                               break;
-                       case AC_OBJ_HOLDER_SERIAL:
-                               this->holderSerial = object;
-                               break;
-                       case AC_OBJ_ENTITY_NAME:
-                               if (!parse_directoryName(object, level, TRUE, &this->entityName))
-                               {
-                                       return FALSE;
-                               }
-                               break;
-                       case AC_OBJ_ISSUER_NAME:
-                               if (!parse_directoryName(object, level, FALSE, &this->issuerName))
-                               {
-                                       return FALSE;
-                               }
-                               break;
-                       case AC_OBJ_SIG_ALG:
-                               this->sigAlg = parse_algorithmIdentifier(object, level, NULL);
-                               break;
-                       case AC_OBJ_SERIAL_NUMBER:
-                               this->serialNumber = object;
-                               break;
-                       case AC_OBJ_NOT_BEFORE:
-                               this->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
-                               break;
-                       case AC_OBJ_NOT_AFTER:
-                               this->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:
-                                                       DBG2("  need to parse authenticationInfo");
-                                                       break;
-                                               case OID_ACCESS_IDENTITY:
-                                                       DBG2("  need to parse accessIdentity");
-                                                       break;
-                                               case OID_CHARGING_IDENTITY:
-                                                       ietfAttr_list_create_from_chunk(object, this->charging, level);
-                                                       break;
-                                               case OID_GROUP:
-                                                       ietfAttr_list_create_from_chunk(object, this->groups, 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;
-                               DBG2("  %s",(critical)?"TRUE":"FALSE");
-                               break;
-                       case AC_OBJ_EXTN_VALUE:
-                               {
-                                       switch (extn_oid)
-                                       {
-                                               case OID_CRL_DISTRIBUTION_POINTS:
-                                                       DBG2("  need to parse crlDistributionPoints");
-                                                       break;
-                                               case OID_AUTHORITY_KEY_ID:
-                                                       x509_parse_authorityKeyIdentifier(object, level,
-                                                                       &this->authKeyID, &this->authKeySerialNumber);
-                                                       break;
-                                               case OID_TARGET_INFORMATION:
-                                                       DBG2("  need to parse targetInformation");
-                                                       break;
-                                               case OID_NO_REV_AVAIL:
-                                                       this->noRevAvail = TRUE;
-                                                       break;
-                                               default:
-                                                       break;
-                                       }
-                               }
-                               break;
-                       case AC_OBJ_ALGORITHM:
-                               this->algorithm = parse_algorithmIdentifier(object, level, NULL);
-                               break;
-                       case AC_OBJ_SIGNATURE:
-                               this->signature = object;
-                               break;
-                       default:
-                               break;
-               }
-               objectID++;
-       }
-       this->installed = time(NULL);
-       return TRUE;
-}
-
-/**
- * Implementation of x509ac_t.list.
- */
-static void list(const private_x509ac_t *this, FILE *out, bool utc)
-{
-       time_t now = time(NULL);
-
-       fprintf(out, "%#T\n", &this->installed, utc);
-
-       if (this->entityName)
-       {
-               fprintf(out, "    holder:    '%D'\n", this->entityName);
-       }
-       if (this->holderIssuer)
-       {
-               fprintf(out, "    hissuer:   '%D'\n", this->holderIssuer);
-       }
-       if (this->holderSerial.ptr)
-       {
-               fprintf(out, "    hserial:    %#B\n", &this->holderSerial);
-       }
-       
-       /* list all group attributes on a single line */
-       fprintf(out, "    groups:     ");
-       ietfAttr_list_list(this->groups, out);
-       fprintf(out, "\n");
-
-       fprintf(out, "    issuer:    '%D'\n", this->issuerName);
-       fprintf(out, "    serial:     %#B\n", &this->serialNumber);
-
-       fprintf(out, "    validity:   not before %#T, ", &this->notBefore, utc);
-       if (now < this->notBefore)
-       {
-               fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
-       }
-       else
-       {
-               fprintf(out, "ok\n");
-       }
-       
-       fprintf(out, "                not after  %#T, ", &this->notAfter, utc);
-       if (now > this->notAfter)
-       {
-               fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
-       }
-       else
-       {
-               fprintf(out, "ok");
-               if (now > this->notAfter - ACERT_WARNING_INTERVAL * 60 * 60 * 24)
-               {
-                       fprintf(out, " (expires in %#V)", &now, &this->notAfter);
-               }
-               fprintf(out, " \n");
-       }
-
-       if (this->authKeyID.ptr)
-       {
-               fprintf(out, "    authkey:    %#B\n", &this->authKeyID);
-       }
-       if (this->authKeySerialNumber.ptr)
-       {
-               fprintf(out, "    aserial:    %#B\n", &this->authKeySerialNumber);
-       }
-}
-
-/**
- * Implements x509ac_t.destroy
- */
-static void destroy(private_x509ac_t *this)
-{
-       DESTROY_IF(this->holderIssuer);
-       DESTROY_IF(this->entityName);
-       DESTROY_IF(this->issuerName);
-       ietfAttr_list_destroy(this->charging);
-       ietfAttr_list_destroy(this->groups);
-       free(this->certificate.ptr);
-       free(this);
-}
-
-/**
- * Described in header.
- */
-x509ac_t *x509ac_create_from_chunk(chunk_t chunk)
-{
-       private_x509ac_t *this = malloc_thing(private_x509ac_t);
-       
-       /* initialize */
-       this->holderIssuer = NULL;
-       this->entityName = NULL;
-       this->issuerName = NULL;
-       this->charging = linked_list_create();
-       this->groups = linked_list_create();
-
-       /* public functions */
-       this->public.is_valid = (err_t (*) (const x509ac_t*,time_t*))is_valid;
-       this->public.is_newer = (bool (*) (const x509ac_t*,const x509ac_t*))is_newer;
-       this->public.equals_holder = (bool (*) (const x509ac_t*,const x509ac_t*))equals_holder;
-       this->public.list = (void (*) (const x509ac_t*,FILE*,bool))list;
-       this->public.destroy = (void (*) (x509ac_t*))destroy;
-
-       if (!parse_certificate(chunk, this))
-       {
-               destroy(this);
-               return NULL;
-       }
-       return &this->public;
-}
-
-/**
- * Described in header.
- */
-x509ac_t *x509ac_create_from_file(const char *filename)
-{
-       bool pgp = FALSE;
-       chunk_t chunk = chunk_empty;
-
-       if (!pem_asn1_load_file(filename, NULL, "attribute certificate", &chunk, &pgp))
-       {
-               return NULL;
-       }
-       return x509ac_create_from_chunk(chunk);
-}
-
diff --git a/src/libstrongswan/crypto/ac.h b/src/libstrongswan/crypto/ac.h
deleted file mode 100644 (file)
index 045c458..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * @file ac.h
- * 
- * @brief Interface of x509ac_t.
- * 
- */
-
-/*
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2007 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.
- *
- * RCSID $Id$
- */
-
-#ifndef AC_H_
-#define AC_H_
-
-#include <library.h>
-
-typedef struct x509ac_t x509ac_t;
-
-/**
- * @brief X.509 attribute certificate.
- * 
- * @b Constructors:
- *  - x509ac_create_from_chunk()
- *  - x509ac_create_from_file()
- *
- * @ingroup crypto
- */
-struct x509ac_t {
-
-       /**
-        * @brief Checks the validity interval of the attribute certificate
-        * 
-        * @param this                  certificate being examined
-        * @param until                 until = min(until, notAfter)
-        * @return                              NULL if the certificate is valid
-        */
-       err_t (*is_valid) (const x509ac_t *this, time_t *until);
-
-       /** @brief Checks if this attr cert is newer than the other attr cert
-        * 
-        * @param this                  calling object
-        * @param other                 other attr cert object
-        * @return                              TRUE if this was issued more recently than other
-        */
-       bool (*is_newer) (const x509ac_t *this, const x509ac_t *other);
-
-       /**
-        * @brief Checks if two attribute certificates belong to the same holder
-        *
-        * @param this                  calling attribute certificate
-        * @param that                  other attribute certificate
-        * @return                              TRUE if same holder
-        */
-       bool (*equals_holder) (const x509ac_t *this, const x509ac_t *other);
-
-       /**
-        * @brief Log the attribute certificate info to out.
-        *
-        * @param this                  calling object
-        * @param out                   stream to write to
-        * @param utc                   TRUE for UTC times, FALSE for local time
-        */
-       void (*list)(const x509ac_t *this, FILE *out, bool utc);
-
-       /**
-        * @brief Destroys the attribute certificate.
-        * 
-        * @param this                  certificate to destroy
-        */
-       void (*destroy) (x509ac_t *this);
-};
-
-/**
- * @brief Read a x509 attribute certificate from a DER encoded blob.
- * 
- * @param chunk        chunk containing DER encoded data
- * @return                     created x509ac_t certificate, or NULL if invalid.
- * 
- * @ingroup crypto
- */
-x509ac_t *x509ac_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Read a x509 attribute certificate from a DER encoded file.
- *
- * @param filename     file containing DER encoded data
- * @return             created x509ac_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509ac_t *x509ac_create_from_file(const char *filename);
-
-#endif /* AC_H_ */
-
diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c
deleted file mode 100644 (file)
index 510e352..0000000
+++ /dev/null
@@ -1,813 +0,0 @@
-/**
- * @file ca.c
- * 
- * @brief Implementation of ca_info_t.
- * 
- */
-
-/*
- * Copyright (C) 2007 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 <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <pthread.h>
-
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "ac.h"
-#include "certinfo.h"
-#include "ocsp.h"
-
-#include <library.h>
-#include <debug.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-#include <utils/fetcher.h>
-
-typedef struct private_ca_info_t private_ca_info_t;
-
-/**
- * Private data of a ca_info_t object.
- */
-struct private_ca_info_t {
-       /**
-        * Public interface for this ca info record
-        */
-       ca_info_t public;
-       
-       /**
-        * Name of the ca info record
-        */
-       char *name;
-
-       /**
-        * Time when ca info record was installed
-        */
-       time_t installed;
-
-       /**
-        * Distinguished Name of the CA
-        */
-       x509_t *cacert;
-       
-       /**
-        * List of attribute certificates
-        */
-       linked_list_t *attrcerts;
-
-       /**
-        * List of crl URIs
-        */
-       linked_list_t *crluris;
-
-       /**
-        * List of ocsp URIs
-        */
-       linked_list_t *ocspuris;
-
-       /**
-        * CRL issued by this ca
-        */
-       crl_t *crl;
-
-       /**
-        * List of certificate info records
-        */
-       linked_list_t *certinfos;
-
-       /**
-        * mutex controls access to the elements:
-        * name, crluris, ocspuris, crl, and certinfos
-        */
-       pthread_mutex_t mutex;
-};
-
-/**
- * static options set by ca_info_set_options()
- */
-static strict_t strict_crl_policy = STRICT_NO;
-static bool cache_crls = FALSE;
-static u_int crl_check_interval = 0;
-
-/**
- * Implements ca_info_t.equals
- */
-static bool equals(const private_ca_info_t *this, const private_ca_info_t *that)
-{
-       return chunk_equals(this->cacert->get_keyid(this->cacert),
-                                               that->cacert->get_keyid(that->cacert));
-}
-
-/**
- * Implements ca_info_t.equals_name_release_info
- */
-static bool equals_name_release_info(private_ca_info_t *this, const char *name)
-{
-       bool found;
-
-       pthread_mutex_lock(&(this->mutex));
-       found = this->name != NULL && streq(this->name, name);
-
-       if (found)
-       {
-               this->crluris->destroy_offset(this->crluris,
-                                                                         offsetof(identification_t, destroy));
-               this->crluris = linked_list_create();
-
-               this->ocspuris->destroy_offset(this->ocspuris,
-                                                                          offsetof(identification_t, destroy));
-               this->ocspuris = linked_list_create();
-
-               free(this->name);
-               this->name = NULL;
-       }
-
-       pthread_mutex_unlock(&(this->mutex));
-       return found;
-}
-
-/**
- * Implements ca_info_t.is_crl_issuer
- */
-static bool is_cert_issuer(private_ca_info_t *this, const x509_t *cert)
-{
-       return cert->is_issuer(cert, this->cacert);
-}
-
-/**
- * Implements ca_info_t.is_crl_issuer
- */
-static bool is_crl_issuer(private_ca_info_t *this, const crl_t *crl)
-{
-       return crl->is_issuer(crl, this->cacert);
-}
-
-/**
- * Implements ca_info_t.is_ca
- */
-static bool is_ca(private_ca_info_t *this)
-{
-       return this->cacert->is_ca(this->cacert);
-}
-
-/**
- * Implements ca_info_t.is_strict
- */
-static bool is_strict(private_ca_info_t *this)
-{
-       bool strict = strict_crl_policy != STRICT_NO;
-
-       if (strict_crl_policy == STRICT_IFURI)
-       {
-               pthread_mutex_lock(&(this->mutex));
-               strict = this->crluris->get_count(this->crluris)   > 0 ||
-                                this->ocspuris->get_count(this->ocspuris) > 0;
-               pthread_mutex_unlock(&(this->mutex));
-       }
-       return strict;
-}
-
-/**
- * Implements ca_info_t.has_crl
- */
-static bool has_crl(private_ca_info_t *this)
-{
-       bool found;
-
-       pthread_mutex_lock(&(this->mutex));
-       found = this->crl != NULL;
-       pthread_mutex_unlock(&(this->mutex));
-
-       return found;
-}
-
-/**
- * Implements ca_info_t.has_certinfos
- */
-static bool has_certinfos(private_ca_info_t *this)
-{
-       bool found;
-
-       pthread_mutex_lock(&(this->mutex));
-       found = this->certinfos->get_count(this->certinfos) > 0;
-       pthread_mutex_unlock(&(this->mutex));
-
-       return found;
-}
-
-/**
- * Implements ca_info_t.add_crl
- */
-static void add_crl(private_ca_info_t *this, crl_t *crl)
-{
-       pthread_mutex_lock(&(this->mutex));
-
-       if (this->crl)
-       {
-               if (crl->is_newer(crl, this->crl))
-               {
-                       this->crl->destroy(this->crl);
-                       this->crl = crl;
-                       DBG1("  this crl is newer - existing crl replaced");
-               }
-               else
-               {
-                       crl->destroy(crl);
-                       DBG1("  this crl is not newer - existing crl retained");
-               }
-       }
-       else
-       {
-               this->crl = crl;
-               DBG2("  crl added");
-       }
-
-       pthread_mutex_unlock(&(this->mutex));
-}
-
-/**
- * Implements ca_info_t.list_crl
- */
-static void list_crl(private_ca_info_t *this, FILE *out, bool utc)
-{
-       pthread_mutex_lock(&this->mutex);
-       this->crl->list(this->crl, out, utc);
-       pthread_mutex_unlock(&this->mutex);
-}
-
-/**
- * Implements ca_info_t.list_certinfos
- */
-static void list_certinfos(private_ca_info_t *this, FILE *out, bool utc)
-{
-       iterator_t *iterator;
-       certinfo_t *certinfo;
-       chunk_t authkey;
-
-       pthread_mutex_lock(&this->mutex);
-
-       authkey = this->cacert->get_subjectKeyID(this->cacert);
-       fprintf(out,"    authname:  '%D'\n", this->cacert->get_subject(this->cacert));
-       fprintf(out,"    authkey:    %#B\n", &authkey);
-
-       iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
-       while (iterator->iterate(iterator, (void**)&certinfo))
-       {
-               time_t nextUpdate, thisUpdate, now;
-               chunk_t serial;
-               
-               now = time(NULL);
-               nextUpdate = certinfo->get_nextUpdate(certinfo);
-               thisUpdate = certinfo->get_thisUpdate(certinfo);
-               serial = certinfo->get_serialNumber(certinfo);
-               
-               fprintf(out, "%#T, until %#T, ", &thisUpdate, utc, &nextUpdate, utc);
-               if (now > nextUpdate)
-               {
-                       fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
-               }
-               else
-               {
-                       fprintf(out, "ok (expires in %#V)\n", &now, &nextUpdate);
-               }
-               fprintf(out, "    serial:     %#B, %N\n", &serial,
-                               cert_status_names, certinfo->get_status(certinfo));
-       }
-       iterator->destroy(iterator);
-
-       pthread_mutex_unlock(&this->mutex);
-}
-
-/**
- * Find an exact copy of an identification in a linked list
- */
-static identification_t* find_identification(linked_list_t *list, identification_t *id)
-{
-       identification_t *found_id = NULL, *current_id;
-
-       iterator_t *iterator = list->create_iterator(list, TRUE);
-
-       while (iterator->iterate(iterator, (void**)&current_id))
-       {
-               if (id->equals(id, current_id))
-               {
-                       found_id = current_id;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-
-       return found_id;
-}
-
-/**
- * Add a unique identification to a linked list
- */
-static identification_t *add_identification(linked_list_t *list, identification_t *id)
-{
-       identification_t *found_id = find_identification(list, id);
-
-       if (found_id)
-       {
-               id->destroy(id);
-               return found_id;
-       }
-       else
-       {
-               list->insert_last(list, (void*)id);
-               return id;
-       }
-}
-
-/**
- * Implements ca_info_t.add_crluri
- */
-static void add_crluri(private_ca_info_t *this, chunk_t uri)
-{
-       if (uri.len < 6 ||
-          (strncasecmp(uri.ptr, "http", 4) != 0  &&
-               strncasecmp(uri.ptr, "ldap", 4) != 0  &&
-               strncasecmp(uri.ptr, "file", 4) != 0  &&
-               strncasecmp(uri.ptr, "ftp",  3) != 0))
-       {
-               DBG1("  invalid crl uri '%.*s'", uri.len, uri.ptr);
-               return;
-       }
-       else
-       {
-               identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
-
-               pthread_mutex_lock(&(this->mutex));
-               add_identification(this->crluris, crluri);
-               pthread_mutex_unlock(&(this->mutex));
-       }
-}
-
-/**
- * Implements ca_info_t.add_ocspuri
- */
-static void add_ocspuri(private_ca_info_t *this, chunk_t uri)
-{
-       if (uri.len < 7 || strncasecmp(uri.ptr, "http", 4) != 0)
-       {
-               DBG1("  invalid ocsp uri '%.*s'", uri.len, uri.ptr);
-               return;
-       }
-       else
-       {
-               identification_t *ocspuri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
-
-               pthread_mutex_lock(&(this->mutex));
-               add_identification(this->ocspuris, ocspuri);
-               pthread_mutex_unlock(&(this->mutex));
-       }
-}
-
-/**
- * Implements ca_info_t.add_info.
- */
-void add_info (private_ca_info_t *this, const private_ca_info_t *that)
-{
-       pthread_mutex_lock(&(this->mutex));
-
-       if (this->name == NULL && that->name != NULL)
-       {
-               this->name = strdup(that->name);
-       }
-
-       pthread_mutex_unlock(&(this->mutex));
-
-       {
-               identification_t *uri;
-
-               iterator_t *iterator = that->crluris->create_iterator(that->crluris, TRUE);
-
-               while (iterator->iterate(iterator, (void**)&uri))
-               {
-                       if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
-                       {
-                               add_crluri(this, uri->get_encoding(uri));
-                       }
-               }
-               iterator->destroy(iterator);
-       }
-
-       {
-               identification_t *uri;
-
-               iterator_t *iterator = that->ocspuris->create_iterator(that->ocspuris, TRUE);
-
-               while (iterator->iterate(iterator, (void**)&uri))
-               {
-                       if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
-                       {
-                               add_ocspuri(this, uri->get_encoding(uri));
-                       }
-               }
-               iterator->destroy(iterator);
-       }
-}
-
-/**
- *  Implements ca_info_t.get_certificate.
- */
-static x509_t* get_certificate(private_ca_info_t* this)
-{
-       return this->cacert;
-}
-
-/**
- * caches a crl by saving it to a given crl directory
- */
-void cache_crl(private_ca_info_t* this, const char *crl_dir, crl_t *crl)
-{
-       char buffer[BUF_LEN];
-       char *path;
-       char *pos = buffer;
-       int len = BUF_LEN;
-       int n;
-
-       chunk_t authKeyID = this->cacert->get_subjectKeyID(this->cacert);
-       chunk_t uri;
-
-       uri.ptr = buffer;
-       uri.len = 7 + strlen(crl_dir) + 1 + 2*authKeyID.len + 4;
-
-       if (uri.len >= BUF_LEN) 
-       {
-               DBG1("file uri exceeds buffer length of %d bytes - crl not saved", BUF_LEN);
-               return;
-       }
-
-       /* print the file uri prefix */
-       n = snprintf(pos, len, "file://");
-       pos += n;  len -= n;
-
-       /* remember the start of the path string */
-       path = pos;
-
-       /* print the default crl directory path */
-       n = snprintf(pos, len, "%s/", crl_dir);
-       pos += n;  len -= n;
-
-       /* create and print a unique crl filename derived from the authKeyID */
-       while (authKeyID.len-- > 0)
-       {
-               n = snprintf(pos, len, "%02x", *authKeyID.ptr++);
-               pos += n; len -= n;
-       }
-
-       /* add the file suffix */
-       n = snprintf(pos, len, ".crl");
-
-       if (crl->write_to_file(crl, path, 0022, TRUE))
-       {
-               identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
-
-               add_identification(this->crluris, crluri);
-       }
-}
-
-/**
- *  Implements ca_info_t.verify_by_crl.
- */
-static cert_status_t verify_by_crl(private_ca_info_t* this, certinfo_t *certinfo,
-                                                                  const char *crl_dir)
-{
-       rsa_public_key_t *issuer_public_key = this->cacert->get_public_key(this->cacert);
-       bool stale;
-
-       pthread_mutex_lock(&(this->mutex));
-       if (this->crl == NULL)
-       {
-               stale = TRUE;
-               DBG1("no crl is locally available");
-       }
-       else
-       {
-               stale = !this->crl->is_valid(this->crl);
-               DBG1("crl is %s", stale? "stale":"valid");
-       }
-
-       if (stale && crl_check_interval > 0)
-       {
-               iterator_t *iterator = this->crluris->create_iterator(this->crluris, TRUE);
-               identification_t *uri;
-               
-               while (iterator->iterate(iterator, (void**)&uri))
-               {
-                       fetcher_t *fetcher;
-                       char uri_string[BUF_LEN];
-                       chunk_t uri_chunk = uri->get_encoding(uri);
-                       chunk_t response_chunk;
-
-                       snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
-                       fetcher = fetcher_create(uri_string);
-                       
-                       response_chunk = fetcher->get(fetcher);
-                       fetcher->destroy(fetcher);
-                       if (response_chunk.ptr != NULL)
-                       {
-                               crl_t *crl = crl_create_from_chunk(response_chunk);
-               
-                               if (crl == NULL)
-                               {
-                                       free(response_chunk.ptr);
-                                       continue;
-                               }
-                               if (!is_crl_issuer(this, crl))
-                               {
-                                       DBG1("  fetched crl has wrong issuer");
-                                       crl->destroy(crl);
-                                       continue;
-                               }
-                               if (!crl->verify(crl, issuer_public_key))
-                               {
-                                       DBG1("fetched crl signature is invalid");
-                                       crl->destroy(crl);
-                                       continue;
-                               }
-                               DBG2("fetched crl signature is valid");
-
-                               if (this->crl == NULL)
-                               {
-                                       this->crl = crl;
-                               }
-                               else if (crl->is_newer(crl, this->crl))
-                               {
-                                       this->crl->destroy(this->crl);
-                                       this->crl = crl;
-                                       DBG1("this crl is newer - existing crl replaced");
-                               }
-                               else
-                               {
-                                       crl->destroy(crl);
-                                       DBG1("this crl is not newer - existing crl retained");
-                                       continue;
-                               }
-                               if (crl->is_valid(crl))
-                               {
-                                       if (cache_crls && strncasecmp(uri_string, "file", 4) != 0)
-                                       {
-                                               cache_crl(this, crl_dir, crl);
-                                       }
-                                       /* we found a valid crl and therefore exit the fetch loop */
-                                       break;
-                               }
-                               else
-                               {
-                                       DBG1("fetched crl is stale");
-                               }
-                       }
-               }
-               iterator->destroy(iterator);
-       }
-
-       if (this->crl)
-       {
-               if (!this->crl->verify(this->crl, issuer_public_key))
-               {
-                       DBG1("crl signature is invalid");
-                       goto ret;
-               }
-               DBG2("crl signature is valid");
-
-               this->crl->get_status(this->crl, certinfo);
-       }
-
-ret:
-       pthread_mutex_unlock(&(this->mutex));
-       return certinfo->get_status(certinfo);
-}
-
-/**
-  * Implements ca_info_t.verify_by_ocsp.
-  */
-static cert_status_t verify_by_ocsp(private_ca_info_t* this,
-                                                                       certinfo_t *certinfo,
-                                                                       credential_store_t *credentials)
-{
-       bool stale;
-       iterator_t *iterator;
-       certinfo_t *cached_certinfo = NULL;
-       int comparison = 1;
-
-       pthread_mutex_lock(&(this->mutex));
-
-       /* do we support OCSP at all? */
-       if (this->ocspuris->get_count(this->ocspuris) == 0)
-       {
-               goto ret;
-       }
-
-       iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
-
-       /* find the list insertion point in alphabetical order */
-       while(iterator->iterate(iterator, (void**)&cached_certinfo))
-       {
-               comparison = certinfo->compare_serialNumber(certinfo, cached_certinfo);
-
-               if (comparison <= 0)
-               {
-                       break;
-               }
-       }
-
-       /* do we have a valid certinfo_t for this serial number in our cache? */
-       if (comparison == 0)
-       {       
-               stale = cached_certinfo->get_nextUpdate(cached_certinfo) < time(NULL);
-               DBG1("ocsp status in cache is %s", stale ? "stale":"fresh");
-       }
-       else
-       {
-               stale = TRUE;
-               DBG1("ocsp status is not in cache");
-       }
-
-       if (stale)
-       {
-               ocsp_t *ocsp;
-
-               ocsp = ocsp_create(this->cacert, this->ocspuris);
-               ocsp->fetch(ocsp, certinfo, credentials);
-               if (certinfo->get_status(certinfo) != CERT_UNDEFINED)
-               {
-                       if (comparison != 0)
-                       {
-                               cached_certinfo = certinfo_create(certinfo->get_serialNumber(certinfo));
-
-                               if (comparison > 0)
-                               {
-                                       this->certinfos->insert_last(this->certinfos, (void *)cached_certinfo);
-                               }
-                               else
-                               {
-                                       iterator->insert_before(iterator, (void *)cached_certinfo);
-                               }
-                       }
-                       cached_certinfo->update(cached_certinfo, certinfo);
-               }
-               ocsp->destroy(ocsp);
-       }
-       else
-       {
-               certinfo->update(certinfo, cached_certinfo);
-       }
-
-       iterator->destroy(iterator);
-
-ret:
-       pthread_mutex_unlock(&(this->mutex));
-       return certinfo->get_status(certinfo);
-}
-
-/**
- * Implements ca_info_t.purge_ocsp
- */
-static void purge_ocsp(private_ca_info_t *this)
-{
-       pthread_mutex_lock(&(this->mutex));
-
-       this->certinfos->destroy_offset(this->certinfos,
-                                                                       offsetof(certinfo_t, destroy));
-       this->certinfos = linked_list_create();
-
-       pthread_mutex_unlock(&(this->mutex));
-}
-
-/**
- * Implements ca_info_t.destroy
- */
-static void destroy(private_ca_info_t *this)
-{
-       this->attrcerts->destroy_offset(this->attrcerts,
-                                                                 offsetof(x509ac_t, destroy));
-       this->crluris->destroy_offset(this->crluris,
-                                                                 offsetof(identification_t, destroy));
-       this->ocspuris->destroy_offset(this->ocspuris,
-                                                                  offsetof(identification_t, destroy));
-       this->certinfos->destroy_offset(this->certinfos,
-                                                                  offsetof(certinfo_t, destroy));
-       DESTROY_IF(this->crl);
-       free(this->name);
-       free(this);
-}
-
-/**
- * list the info of this CA
- */
-static void list(private_ca_info_t* this, FILE* out, bool utc)
-{
-       chunk_t chunk;
-       identification_t *uri;
-       iterator_t *iterator;
-       bool first;
-       
-       pthread_mutex_lock(&(this->mutex));
-       fprintf(out, "%#T", &this->installed, utc);
-
-       if (this->name)
-       {
-               fprintf(out, ", \"%s\"\n", this->name);
-       }
-       else
-       {
-               fprintf(out, "\n");
-       }
-
-       fprintf(out, "    authname:  '%D'\n", this->cacert->get_subject(this->cacert));
-       chunk = this->cacert->get_subjectKeyID(this->cacert);
-       fprintf(out, "    authkey:    %#B\n", &chunk);
-       chunk = this->cacert->get_keyid(this->cacert);
-       fprintf(out, "    keyid:      %#B\n", &chunk);
-       
-       first = TRUE;
-       iterator = this->crluris->create_iterator(this->crluris, TRUE);
-       while (iterator->iterate(iterator, (void**)&uri))
-       {
-               fprintf(out, "    %s   '%D'\n",  first ? "crluris:":"        ", uri);
-               first = FALSE;
-       }
-       iterator->destroy(iterator);
-       
-       first = TRUE;
-       iterator = this->ocspuris->create_iterator(this->ocspuris, TRUE);
-       while (iterator->iterate(iterator, (void**)&uri))
-       {
-               fprintf(out, "    %s  '%D'\n", first ? "ocspuris:":"         ", uri);
-               first = FALSE;
-       }
-       iterator->destroy(iterator);
-       pthread_mutex_unlock(&(this->mutex));
-}
-
-/*
- * Described in header.
- */
-void ca_info_set_options(strict_t strict, bool cache, u_int interval)
-{
-       strict_crl_policy = strict;
-       cache_crls = cache;
-       crl_check_interval = interval;
-}
-
-/*
- * Described in header.
- */
-ca_info_t *ca_info_create(const char *name, x509_t *cacert)
-{
-       private_ca_info_t *this = malloc_thing(private_ca_info_t);
-       
-       /* initialize */
-       this->installed = time(NULL);
-       this->name = (name == NULL)? NULL:strdup(name);
-       this->cacert = cacert;
-       this->attrcerts = linked_list_create();
-       this->crluris = linked_list_create();
-       this->ocspuris = linked_list_create();
-       this->certinfos = linked_list_create();
-       this->crl = NULL;
-       
-       /* initialize the mutex */
-       pthread_mutex_init(&(this->mutex), NULL);
-
-       /* public functions */
-       this->public.equals = (bool (*) (const ca_info_t*,const ca_info_t*))equals;
-       this->public.equals_name_release_info = (bool (*) (ca_info_t*,const char*))equals_name_release_info;
-       this->public.is_cert_issuer = (bool (*) (ca_info_t*,const x509_t*))is_cert_issuer;
-       this->public.is_crl_issuer = (bool (*) (ca_info_t*,const crl_t*))is_crl_issuer;
-       this->public.is_ca = (bool (*) (ca_info_t*))is_ca;
-       this->public.is_strict = (bool (*) (ca_info_t*))is_strict;
-       this->public.add_info = (void (*) (ca_info_t*,const ca_info_t*))add_info;
-       this->public.add_crl = (void (*) (ca_info_t*,crl_t*))add_crl;
-       this->public.has_crl = (bool (*) (ca_info_t*))has_crl;
-       this->public.has_certinfos = (bool (*) (ca_info_t*))has_certinfos;
-       this->public.list = (void (*) (ca_info_t*,FILE*,bool))list;
-       this->public.list_crl = (void (*) (ca_info_t*,FILE*,bool))list_crl;
-       this->public.list_certinfos = (void (*) (ca_info_t*,FILE*,bool))list_certinfos;
-       this->public.add_crluri = (void (*) (ca_info_t*,chunk_t))add_crluri;
-       this->public.add_ocspuri = (void (*) (ca_info_t*,chunk_t))add_ocspuri;
-       this->public.get_certificate = (x509_t* (*) (ca_info_t*))get_certificate;
-       this->public.verify_by_crl = (cert_status_t (*) (ca_info_t*,certinfo_t*, const char*))verify_by_crl;
-       this->public.verify_by_ocsp = (cert_status_t (*) (ca_info_t*,certinfo_t*,credential_store_t*))verify_by_ocsp;
-       this->public.purge_ocsp = (void (*) (ca_info_t*))purge_ocsp;
-       this->public.destroy = (void (*) (ca_info_t*))destroy;
-
-       return &this->public;
-}
diff --git a/src/libstrongswan/crypto/ca.h b/src/libstrongswan/crypto/ca.h
deleted file mode 100644 (file)
index ff6271b..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/**
- * @file ca.h
- * 
- * @brief Interface of ca_info_t.
- * 
- */
-
-/*
- * Copyright (C) 2007 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.
- */
-
-#ifndef CA_H_
-#define CA_H_
-
-typedef struct ca_info_t ca_info_t;
-
-#include <library.h>
-
-#include "x509.h"
-#include "crl.h"
-
-#define MAX_CA_PATH_LEN                7
-
-/*forward declaration */
-struct credential_store_t;
-
-/**
- * @brief X.509 certification authority information record
- * 
- * @b Constructors:
- *  - ca_info_create()
- * 
- * @ingroup transforms
- */
-struct ca_info_t {
-
-       /**
-        * @brief Compare two ca info records
-        *
-        * Comparison is done via the keyid of the ca certificate
-     *
-        * @param this                  first ca info object
-        * @param that                  second ca info objct
-        * @return                              TRUE if a match is found
-        */
-       bool (*equals) (const ca_info_t *this, const ca_info_t* that);
-
-       /**
-        * @brief If the ca info record has the same name then release the name and URIs
-        * 
-        * @param this                  ca info object
-        * @return                              TRUE if a match is found
-        */
-       bool (*equals_name_release_info) (ca_info_t *this, const char *name);
-
-       /**
-        * @brief Checks if a certificate was issued by this ca
-        * 
-        * @param this                  ca info object
-        * @param cert                  certificate to be checked
-        * @return                              TRUE if the issuing ca has been found
-        */
-       bool (*is_cert_issuer) (ca_info_t *this, const x509_t *cert);
-
-       /**
-        * @brief Checks if a crl was issued by this ca
-        * 
-        * @param this                  ca info object
-        * @param crl                   crl to be checked
-        * @return                              TRUE if the issuing ca has been found
-        */
-       bool (*is_crl_issuer) (ca_info_t *this, const crl_t *crl);
-
-       /**
-        * @brief Checks if the ca certificate has the isCA flag set
-        *
-        * @param this                  ca info object
-        * @return                              TRUE if the isCA flag is set
-        */
-       bool (*is_ca) (ca_info_t *this);
-
-       /**
-        * @brief Checks if the ca enforces a strict crl policy
-        * 
-        * @param this                  ca info object
-        * @return                              TRUE if the crl policy is strict
-        */
-       bool (*is_strict) (ca_info_t *this);
-
-       /**
-        * @brief Merges info from a secondary ca info object
-        * 
-        * @param this                  primary ca info object
-        * @param that                  secondary ca info object
-        */
-       void (*add_info) (ca_info_t *this, const ca_info_t *that);
-
-       /**
-        * @brief Adds a new or replaces an obsoleted CRL
-        * 
-        * @param this                  ca info object
-        * @param crl                   crl to be added
-        */
-       void (*add_crl) (ca_info_t *this, crl_t *crl);
-
-       /**
-        * @brief Does the CA have a CRL?
-        * 
-        * @param this                  ca info object
-        * @return                              TRUE if crl is available
-        */
-       bool (*has_crl) (ca_info_t *this);
-
-       /**
-        * @brief Does the CA have OCSP certinfos?
-        * 
-        * @param this                  ca info object
-        * @return                              TRUE if there are any certinfos
-        */
-       bool (*has_certinfos) (ca_info_t *this);
-
-       /**
-        * @brief Print the CA info onto the console
-        * 
-        * @param this                  ca info object
-        * @param out                   output stream
-        * @param utc                   TRUE -  utc
-                                                       FALSE - local time
-        */
-       void (*list) (ca_info_t *this, FILE *out, bool utc);
-
-       /**
-        * @brief List the CRL onto the console
-        * 
-        * @param this                  ca info object
-        * @param out                   output stream
-        * @param utc                   TRUE -  utc
-                                                       FALSE - local time
-        */
-       void (*list_crl) (ca_info_t *this, FILE *out, bool utc);
-
-       /**
-        * @brief List the OCSP certinfos onto the console
-        * 
-        * @param this                  ca info object
-        * @param out                   output stream
-        * @param utc                   TRUE -  utc
-                                                       FALSE - local time
-        */
-       void (*list_certinfos) (ca_info_t *this, FILE *out, bool utc);
-
-       /**
-        * @brief Adds a CRL URI to a list
-        * 
-        * @param this                  ca info object
-        * @param uri                   crl uri to be added
-        */
-       void (*add_crluri) (ca_info_t *this, chunk_t uri);
-
-       /**
-        * @brief Adds a OCSP URI to a list
-        * 
-        * @param this                  ca info object
-        * @param uri                   ocsp uri to be added
-        */
-       void (*add_ocspuri) (ca_info_t *this, chunk_t uri);
-
-       /**
-        * @brief Get the ca certificate
-        * 
-        * @param this                  ca info object
-        * @return                              ca certificate
-        */
-       x509_t* (*get_certificate) (ca_info_t *this);
-
-       /**
-        * @brief Verify the status of a certificate by CRL
-        * 
-        * @param this                  ca info object
-        * @param certinfo              detailed certificate status information
-        * @param crl_dir               directory where fetched crls should be stored
-        * @return                              certificate status
-        */
-       cert_status_t (*verify_by_crl) (ca_info_t *this, certinfo_t *certinfo, const char *crl_dir);
-
-       /**
-        * @brief Verify the status of a certificate by OCSP
-        * 
-        * @param this                  ca info object
-        * @param certinfo              detailed certificate status information
-        * @param credentials   credential store needed for trust path verification
-        * @return                              certificate status
-        */
-       cert_status_t (*verify_by_ocsp) (ca_info_t* this, certinfo_t* certinfo, struct credential_store_t* credentials);
-
-       /**
-        * @brief Purge the OCSP certinfos of a ca info record
-        * 
-        * @param this                  ca info object
-        */
-       void (*purge_ocsp) (ca_info_t *this);
-
-       /**
-        * @brief Destroys a ca info record
-        * 
-        * @param this                  ca info to destroy
-        */
-       void (*destroy) (ca_info_t *this);
-};
-
-/**
- * @brief Set ca info options
- * 
- * @param cache                TRUE if crls shall be cached by storing them
- * @param interval     crl_check_interval to be set in seconds
- * 
- * @ingroup crypto
- */
-void ca_info_set_options(strict_t strict, bool cache, u_int interval);
-
-/**
- * @brief Create a ca info record
- * 
- * @param name                 name of the ca info record
- * @param cacert       path to the ca certificate
- * @return                     created ca_info_t, or NULL if invalid.
- * 
- * @ingroup crypto
- */
-ca_info_t *ca_info_create(const char *name, x509_t *cacert);
-
-#endif /* CA_H_ */
diff --git a/src/libstrongswan/crypto/certinfo.c b/src/libstrongswan/crypto/certinfo.c
deleted file mode 100644 (file)
index 8a125e2..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/**
- * @file certinfo.c
- * 
- * @brief Implementation of certinfo_t.
- * 
- */
-
-/*
- * Copyright (C) 2006 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 <time.h>
-#include <stdio.h>
-
-#include <library.h>
-
-#include "certinfo.h"
-
-typedef struct private_certinfo_t private_certinfo_t;
-
-/**
- * Private data of a certinfo_t object.
- */
-struct private_certinfo_t {
-       /**
-        * Public interface for this certificate status information object.
-        */
-       certinfo_t public;
-       
-       /**
-        * Serial number of the certificate
-        */
-       chunk_t serialNumber;
-
-       /**
-        * Certificate status
-        */
-       cert_status_t status;
-
-       /**
-        * Certificate status is for one-time use only
-        */
-       bool once;
-
-       /**
-        * Time when the certificate status info was generated
-        */
-       time_t thisUpdate;
-
-       /**
-        * Time when an updated certifcate status info will be available
-        */
-       time_t nextUpdate;
-
-       /**
-        * Time of certificate revocation
-        */
-    time_t revocationTime;
-
-       /**
-        * Reason of certificate revocation
-        */
-    crl_reason_t revocationReason;
-};
-
-ENUM(cert_status_names, CERT_GOOD, CERT_UNTRUSTED,
-       "good",
-       "revoked",
-       "unknown",
-       "unknown",
-       "untrusted",
-);
-
-ENUM(crl_reason_names, REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL,
-       "unspecified",
-       "key compromise",
-       "ca compromise",
-       "affiliation changed",
-       "superseded",
-       "cessation of operation",
-       "certificate hold",
-       "reason #7",
-       "remove from crl",
-);
-
-/**
- * Implements certinfo_t.compare_serialNumber
- */
-static int compare_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that)
-{
-       return chunk_compare(this->serialNumber, that->serialNumber);
-}
-
-/**
- * Implements certinfo_t.equals_serialNumber
- */
-static bool equals_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that)
-{
-       return chunk_equals(this->serialNumber, that->serialNumber);
-}
-
-/**
- * Implements certinfo_t.get_serialNumber
- */
-static chunk_t get_serialNumber(const private_certinfo_t *this)
-{
-       return this->serialNumber;
-}
-
-/**
- * Implements certinfo_t.set_status
- */
-static void set_status(private_certinfo_t *this, cert_status_t status)
-{
-       this->status = status;
-}
-
-/**
- * Implements certinfo_t.get_status
- */
-static cert_status_t get_status(const private_certinfo_t *this)
-{
-       return this->status;
-}
-
-/**
- * Implements certinfo_t.set_thisUpdate
- */
-static void set_thisUpdate(private_certinfo_t *this, time_t thisUpdate)
-{
-       this->thisUpdate = thisUpdate;
-}
-
-/**
- * Implements certinfo_t.get_thisUpdate
- */
-static time_t get_thisUpdate(const private_certinfo_t *this)
-{
-       return this->thisUpdate;
-}
-
-/**
- * Implements certinfo_t.set_nextUpdate
- */
-static void set_nextUpdate(private_certinfo_t *this, time_t nextUpdate)
-{
-       this->nextUpdate = nextUpdate;
-}
-
-/**
- * Implements certinfo_t.get_nextUpdate
- */
-static time_t get_nextUpdate(const private_certinfo_t *this)
-{
-       return this->nextUpdate;
-}
-
-/**
- * Implements certinfo_t.set_revocationTime
- */
-static void set_revocationTime(private_certinfo_t *this, time_t revocationTime)
-{
-       this->revocationTime = revocationTime;
-}
-
-/**
- * Implements certinfo_t.get_revocationTime
- */
-static time_t get_revocationTime(const private_certinfo_t *this)
-{
-       return this->revocationTime;
-}
-
-/**
- * Implements certinfo_t.set_revocationReason
- */
-static void set_revocationReason(private_certinfo_t *this, crl_reason_t reason)
-{
-       this->revocationReason = reason;
-}
-
-/**
- * Implements certinfo_t.get_revocationReason
- */
-static crl_reason_t get_revocationReason(const private_certinfo_t *this)
-{
-       return this->revocationReason;
-}
-
-/**
- * Implements certinfo_t.update
- */
-static void update(private_certinfo_t *this, const private_certinfo_t *that)
-{
-       if (equals_serialNumber(this, that))
-       {
-               chunk_t this_serialNumber = this->serialNumber;
-
-               *this = *that;
-               this->serialNumber = this_serialNumber;
-       }
-}
-
-/**
- * Implements certinfo_t.destroy
- */
-static void destroy(private_certinfo_t *this)
-{
-       free(this->serialNumber.ptr);
-       free(this);
-}
-
-/*
- * Described in header.
- */
-certinfo_t *certinfo_create(chunk_t serial)
-{
-       private_certinfo_t *this = malloc_thing(private_certinfo_t);
-       
-       /* initialize */
-       this->serialNumber = chunk_clone(serial);
-       this->status = CERT_UNDEFINED;
-       this->thisUpdate = UNDEFINED_TIME;
-       this->nextUpdate = UNDEFINED_TIME;
-       this->revocationTime = UNDEFINED_TIME;
-       this->revocationReason = REASON_UNSPECIFIED;
-
-       /* public functions */
-       this->public.compare_serialNumber = (int (*) (const certinfo_t*,const certinfo_t*))compare_serialNumber;
-       this->public.equals_serialNumber = (bool (*) (const certinfo_t*,const certinfo_t*))equals_serialNumber;
-       this->public.get_serialNumber = (chunk_t (*) (const certinfo_t*))get_serialNumber;
-       this->public.set_status = (void (*) (certinfo_t*,cert_status_t))set_status;
-       this->public.get_status = (cert_status_t (*) (const certinfo_t*))get_status;
-       this->public.set_thisUpdate = (void (*) (certinfo_t*,time_t))set_thisUpdate;
-       this->public.get_thisUpdate = (time_t (*) (const certinfo_t*))get_thisUpdate;
-       this->public.set_nextUpdate = (void (*) (certinfo_t*,time_t))set_nextUpdate;
-       this->public.get_nextUpdate = (time_t (*) (const certinfo_t*))get_nextUpdate;
-       this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime;
-       this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime;
-       this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason;
-       this->public.get_revocationReason = (crl_reason_t(*) (const certinfo_t*))get_revocationReason;
-       this->public.update = (void (*) (certinfo_t*, const certinfo_t*))update;
-       this->public.destroy = (void (*) (certinfo_t*))destroy;
-
-       return &this->public;
-}
diff --git a/src/libstrongswan/crypto/certinfo.h b/src/libstrongswan/crypto/certinfo.h
deleted file mode 100644 (file)
index 476befd..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/**
- * @file certinfo.h
- * 
- * @brief Interface of certinfo_t.
- * 
- */
-
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef CERTINFO_H_
-#define CERTINFO_H_
-
-typedef enum cert_status_t cert_status_t;
-typedef enum crl_reason_t crl_reason_t;
-typedef struct certinfo_t certinfo_t;
-
-#include <library.h>
-
-/**
- * RFC 2560 OCSP - certificate status
- */
-enum cert_status_t {
-       CERT_GOOD =             0,
-       CERT_REVOKED =          1,
-       CERT_UNKNOWN =          2,
-       CERT_UNDEFINED =        3,
-       CERT_UNTRUSTED =        4  /* private use */
-};
-
-extern enum_name_t *cert_status_names;
-
-/**
- * RFC 2459 CRL reason codes
- */
-enum crl_reason_t {
-    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
-};
-
-extern enum_name_t *crl_reason_names;
-
-/**
- * @brief X.509 certificate status information
- *
- * @ingroup transforms
- */
-struct certinfo_t {
-
-       /**
-        * @brief Check if both certinfo objects have the same serialNumber.
-        * 
-        * @param this                          calling object
-        * @param that                          second certinfo_t object
-        * @return                                      TRUE if the same serialNumber
-        */
-       bool (*equals_serialNumber) (const certinfo_t *this, const certinfo_t *that);
-
-       /**
-        * @brief Compares two serial numbers.
-        * 
-        * @param this                          calling object
-        * @param that                          second certinfo_t object
-        * @return                                      negative if this is smaller than that
-        *                                                      zero if this equals that
-        *                                                      positive if this is greater than that
-        */
-       int (*compare_serialNumber) (const certinfo_t *this, const certinfo_t *that);
-
-       /**
-        * @brief Get serial number.
-        *
-        * @param this                          calling object
-        * @return                                      serialNumber
-        */
-       chunk_t (*get_serialNumber) (const certinfo_t *this);
-
-       /**
-        * @brief Set certificate status.
-        *
-        * @param this                          calling object
-        * @param status                        status
-        */
-       void (*set_status) (certinfo_t *this, cert_status_t status);
-
-       /**
-        * @brief Get certificate status.
-        *
-        * @param this                          calling object
-        * @return                                      status
-        */
-       cert_status_t (*get_status) (const certinfo_t *this);
-
-       /**
-        * @brief Set thisUpdate.
-        *
-        * @param this                          calling object
-        * @param thisUpdate            thisUpdate
-        */
-       void (*set_thisUpdate) (certinfo_t *this, time_t thisUpdate);
-
-       /**
-        * @brief Get thisUpdate.
-        *
-        * @param this                          calling object
-        * @return                                      thisUpdate
-        */
-       time_t (*get_thisUpdate) (const certinfo_t *this);
-
-       /**
-        * @brief Set nextUpdate.
-        *
-        * @param this                          calling object
-        * @param                                       nextUpdate
-        */
-       void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate);
-
-       /**
-        * @brief Get nextUpdate.
-        *
-        * @param this                          calling object
-        * @return                                      nextUpdate
-        */
-       time_t (*get_nextUpdate) (const certinfo_t *this);
-
-       /**
-        * @brief Set revocationTime.
-        *
-        * @param this                          calling object
-        * @param revocationTime        revocationTime
-        */
-       void (*set_revocationTime) (certinfo_t *this, time_t revocationTime);
-
-       /**
-        * @brief Get revocationTime.
-        *
-        * @param this                          calling object
-        * @return                                      revocationTime
-        */
-       time_t (*get_revocationTime) (const certinfo_t *this);
-
-       /**
-        * @brief Set revocationReason.
-        *
-        * @param this                          calling object
-        * @param reason                        revocationReason
-        */
-       void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason);
-
-       /**
-        * @brief Get revocationReason.
-        *
-        * @param this                          calling object
-        * @return                                      revocationReason
-        */
-       crl_reason_t (*get_revocationReason) (const certinfo_t *this);
-
-       /**
-        * @brief Set revocationReason.
-        *
-        * @param this                          calling object to be updated
-        * @param that                          object containing updated information
-        */
-       void (*update) (certinfo_t *this, const certinfo_t *that);
-
-       /**
-        * @brief Destroys the certinfo_t object.
-        * 
-        * @param this                  certinfo_t to destroy
-        */
-       void (*destroy) (certinfo_t *this);
-
-};
-
-/**
- * @brief Create a certinfo_t object.
- * 
- * @param serial       chunk serial number of the certificate
- * @return                     created certinfo_t object
- * 
- * @ingroup transforms
- */
-certinfo_t *certinfo_create(chunk_t serial);
-
-#endif /* CERTINFO_H_ */
diff --git a/src/libstrongswan/crypto/crl.c b/src/libstrongswan/crypto/crl.c
deleted file mode 100755 (executable)
index 024d962..0000000
+++ /dev/null
@@ -1,536 +0,0 @@
-/**
- * @file crl.c
- * 
- * @brief Implementation of crl_t.
- * 
- */
-
-/*
- * Copyright (C) 2006 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.
- *
- * RCSID $Id$
- */
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <library.h>
-#include <debug.h>
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-#include "certinfo.h"
-#include "x509.h"
-#include "crl.h"
-
-#define CRL_WARNING_INTERVAL   7       /* days */
-
-/* access structure for a revoked certificate */
-
-typedef struct revokedCert_t revokedCert_t;
-
-struct revokedCert_t {
-       chunk_t       userCertificate;
-       time_t        revocationDate;
-       crl_reason_t  revocationReason;
-};
-
-typedef struct private_crl_t private_crl_t;
-
-/**
- * Private data of a crl_t object.
- */
-struct private_crl_t {
-       /**
-        * Public interface for this crl.
-        */
-       crl_t public;
-       
-       /**
-        * Time when crl was installed
-        */
-       time_t installed;
-
-       /**
-        * List of crlDistributionPoints
-        */
-       linked_list_t *crlDistributionPoints;
-
-       /**
-        * X.509 crl in DER format
-        */
-       chunk_t certificateList;
-
-       /**
-        * X.509 crl body over which signature is computed
-        */
-       chunk_t tbsCertList;
-
-       /**
-        * Version of the X.509 crl
-        */
-       u_int version;
-       
-       /**
-        * Signature algorithm
-        */
-       int sigAlg;
-       
-       /**
-        * ID representing the crl issuer
-        */
-       identification_t *issuer;
-       
-       /**
-        * CRL number
-        */
-       chunk_t crlNumber;
-
-       /**
-        * Time when the crl was generated
-        */
-       time_t thisUpdate;
-
-       /**
-        * Time when an update crl will be available
-        */
-       time_t nextUpdate;
-
-       /**
-        * List of identification_t's representing subjectAltNames
-        */
-       linked_list_t *revokedCertificates;
-       
-       /**
-        * Authority Key Identifier
-        */
-       chunk_t authKeyID;
-
-       /**
-        * Authority Key Serial Number
-        */
-       chunk_t authKeySerialNumber;
-       
-       /**
-        * Signature algorithm (must be identical to sigAlg)
-        */
-       int algorithm;
-       
-       /**
-        * Signature
-        */
-       chunk_t signature;
-};
-
-/**
-  * 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
-#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_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
-
-/**
- * Parses a CRL revocation reason code
- */
-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;
-       }
-       DBG2("  '%N'", crl_reason_names, reason);
-
-       return reason;
-}
-
-/**
- *  Parses an X.509 Certificate Revocation List (CRL)
- */
-bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
-{
-       asn1_ctx_t ctx;
-       bool critical;
-       chunk_t extnID;
-       chunk_t userCertificate = chunk_empty;
-       revokedCert_t *revokedCert = NULL;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
-       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;
-                               DBG2("  v%d", crl->version);
-                               break;
-                       case CRL_OBJ_SIG_ALG:
-                               crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
-                               break;
-                       case CRL_OBJ_ISSUER:
-                               crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
-                               DBG2("  '%D'", crl->issuer);
-                               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:
-                               revokedCert = malloc_thing(revokedCert_t);
-                               revokedCert->userCertificate = userCertificate;
-                               revokedCert->revocationDate = parse_time(object, level);
-                               revokedCert->revocationReason = REASON_UNSPECIFIED;
-                               crl->revokedCertificates->insert_last(crl->revokedCertificates, (void *)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;
-                               DBG2("  %s",(critical)?"TRUE":"FALSE");
-                               break;
-                       case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
-                       case CRL_OBJ_EXTN_VALUE:
-                               {
-                                       int extn_oid = known_oid(extnID);
-
-                                       if (revokedCert && extn_oid == OID_CRL_REASON_CODE)
-                                       {
-                                               revokedCert->revocationReason = parse_crl_reasonCode(object);
-                                       }
-                                       else if (extn_oid == OID_AUTHORITY_KEY_ID)
-                                       {
-                                               x509_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;
-                                       }
-                               }
-                               break;
-                       case CRL_OBJ_ALGORITHM:
-                               crl->algorithm = parse_algorithmIdentifier(object, level, NULL);
-                               if (crl->algorithm != crl->sigAlg)
-                               {
-                                       DBG1("  signature algorithms do not agree");
-                                       return FALSE;
-                               }
-                               break;
-                       case CRL_OBJ_SIGNATURE:
-                               crl->signature = object;
-                               break;
-                       default:
-                               break;
-               }
-               objectID++;
-       }
-       time(&crl->installed);
-       return TRUE;
-}
-
-/**
- * Implements crl_t.is_valid
- */
-static bool is_valid(const private_crl_t *this)
-{
-       time_t current_time = time(NULL);
-       
-       DBG2("  this update : %T", &this->thisUpdate);
-       DBG2("  current time: %T", &current_time);
-       DBG2("  next update:  %T", &this->nextUpdate);
-
-       return current_time < this->nextUpdate;
-}
-
-/**
- * Implements crl_t.get_issuer
- */
-static identification_t *get_issuer(const private_crl_t *this)
-{
-       return this->issuer;
-}
-
-/**
- * Implements crl_t.equals_issuer
- */
-static bool equals_issuer(const private_crl_t *this, const private_crl_t *other)
-{
-       return (this->authKeyID.ptr)
-                       ? chunk_equals(this->authKeyID, other->authKeyID)
-                       : (this->issuer->equals(this->issuer, other->issuer)
-                          && chunk_equals_or_null(this->authKeySerialNumber, other->authKeySerialNumber));
-}
-
-/**
- * Implements crl_t.is_issuer
- */
-static bool is_issuer(const private_crl_t *this, const x509_t *issuer)
-{
-       return (this->authKeyID.ptr)
-                       ? chunk_equals(this->authKeyID, issuer->get_subjectKeyID(issuer))
-                       : (this->issuer->equals(this->issuer, issuer->get_subject(issuer))
-                          && chunk_equals_or_null(this->authKeySerialNumber, issuer->get_serialNumber(issuer)));
-}
-
-/**
- * Implements crl_t.is_newer
- */
-static bool is_newer(const private_crl_t *this, const private_crl_t *other)
-{
-       return (this->nextUpdate > other->nextUpdate);
-}
-
-/**
- * Implements crl_t.verify
- */
-static bool verify(const private_crl_t *this, const rsa_public_key_t *signer)
-{
-       hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->algorithm);
-
-       if (algorithm == HASH_UNKNOWN)
-       {
-               DBG1("  unknown signature algorithm");
-               return FALSE;
-       }
-       return signer->verify_emsa_pkcs1_signature(signer, algorithm, this->tbsCertList, this->signature) == SUCCESS;
-}
-
-/**
- * Implements crl_t.get_status
- */
-static void get_status(const private_crl_t *this, certinfo_t *certinfo)
-{
-       chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
-       iterator_t *iterator;
-       revokedCert_t *revokedCert;
-       
-       certinfo->set_nextUpdate(certinfo, this->nextUpdate);
-       certinfo->set_status(certinfo, CERT_GOOD);
-       
-       iterator = this->revokedCertificates->create_iterator(this->revokedCertificates, TRUE);
-       while (iterator->iterate(iterator, (void**)&revokedCert))
-       {
-               if (chunk_equals(serialNumber, revokedCert->userCertificate))
-               {
-                       certinfo->set_status(certinfo, CERT_REVOKED);
-                       certinfo->set_revocationTime(certinfo, revokedCert->revocationDate);
-                       certinfo->set_revocationReason(certinfo, revokedCert->revocationReason);
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-}
-
-/**
- * Implements crl_t.write_to_file.
- */
-static bool write_to_file(private_crl_t *this, const char *path, mode_t mask, bool force)
-{
-       return chunk_write(this->certificateList, path, "crl", mask, force);
-}
-
-/**
- * Implements crl_t.destroy
- */
-static void destroy(private_crl_t *this)
-{
-       this->revokedCertificates->destroy_function(this->revokedCertificates, free);
-       this->crlDistributionPoints->destroy_offset(this->crlDistributionPoints,
-                                                                                               offsetof(identification_t, destroy));
-       DESTROY_IF(this->issuer);
-       free(this->certificateList.ptr);
-       free(this);
-}
-
-/**
- * Implementation of crl_t.list.
- */
-static void list(private_crl_t *this, FILE* out, bool utc)
-{
-       time_t now;
-       
-       now = time(NULL);
-       
-       fprintf(out, "%#T, revoked certs: %d\n", &this->installed, utc,
-                                          this->revokedCertificates->get_count(this->revokedCertificates));
-       fprintf(out, "    issuer:    '%D'\n", this->issuer);
-       if (this->crlNumber.ptr)
-       {
-               fprintf(out, "    crlnumber:  %#B\n", &this->crlNumber);
-       }
-       fprintf(out, "    updates:    this %#T\n", &this->thisUpdate, utc);
-       fprintf(out, "                next %#T ",  &this->nextUpdate, utc);
-       if (this->nextUpdate == UNDEFINED_TIME)
-       {
-               fprintf(out, "ok (expires never)\n");
-       }
-       else if (now > this->nextUpdate)
-       {
-               fprintf(out, "expired (%#V ago)\n", &now, &this->nextUpdate);
-       }
-       else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
-       {
-               fprintf(out, "ok (expires in %#V)\n", &now, &this->nextUpdate);
-       }
-       else
-       {
-               fprintf(out, "ok\n");
-       }
-       if (this->authKeyID.ptr)
-       {
-               fprintf(out, "    authkey:    %#B\n", &this->authKeyID);
-       }
-       if (this->authKeySerialNumber.ptr)
-       {
-               fprintf(out, "    aserial:    %#B\n", &this->authKeySerialNumber);
-       }
-}
-
-/*
- * Described in header.
- */
-crl_t *crl_create_from_chunk(chunk_t chunk)
-{
-       private_crl_t *this = malloc_thing(private_crl_t);
-       
-       /* initialize */
-       this->crlDistributionPoints = linked_list_create();
-       this->tbsCertList = chunk_empty;
-       this->issuer = NULL;
-       this->crlNumber = chunk_empty;
-       this->revokedCertificates = linked_list_create();
-       this->authKeyID = chunk_empty;
-       this->authKeySerialNumber = chunk_empty;
-       
-       /* public functions */
-       this->public.get_issuer = (identification_t* (*) (const crl_t*))get_issuer;
-       this->public.equals_issuer = (bool (*) (const crl_t*,const crl_t*))equals_issuer;
-       this->public.is_issuer = (bool (*) (const crl_t*,const x509_t*))is_issuer;
-       this->public.is_valid = (bool (*) (const crl_t*))is_valid;
-       this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer;
-       this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify;
-       this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
-       this->public.write_to_file = (bool (*) (const crl_t*,const char*,mode_t,bool))write_to_file;
-       this->public.list = (void(*)(crl_t*, FILE* out, bool utc))list;
-       this->public.destroy = (void (*) (crl_t*))destroy;
-       
-       if (!parse_x509crl(chunk, 0, this))
-       {
-               destroy(this);
-               return NULL;
-       }
-
-       return &this->public;
-}
-
-/*
- * Described in header.
- */
-crl_t *crl_create_from_file(const char *filename)
-{
-       bool pgp = FALSE;
-       chunk_t chunk = chunk_empty;
-
-       if (!pem_asn1_load_file(filename, NULL, "crl", &chunk, &pgp))
-       {
-               return NULL;
-       }
-       return crl_create_from_chunk(chunk);
-}
diff --git a/src/libstrongswan/crypto/crl.h b/src/libstrongswan/crypto/crl.h
deleted file mode 100755 (executable)
index 68cc049..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * @file crl.h
- * 
- * @brief Interface of crl_t.
- * 
- */
-
-/*
- * Copyright (C) 2006 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.
- *
- * RCSID $Id$
- */
-
-#ifndef CRL_H_
-#define CRL_H_
-
-typedef struct crl_t crl_t;
-
-#include <library.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <crypto/certinfo.h>
-#include <utils/identification.h>
-#include <utils/iterator.h>
-
-/**
- * @brief X.509 certificate revocation list
- * 
- * @b Constructors:
- *  - crl_create_from_chunk()
- *  - crl_create_from_file()
- * 
- * @ingroup transforms
- */
-struct crl_t {
-
-       /**
-        * @brief Get the crl's issuer ID.
-        * 
-        * The resulting ID is always a identification_t
-        * of type ID_DER_ASN1_DN.
-        * 
-        * @param this                          calling object
-        * @return                                      issuers ID
-        */
-       identification_t *(*get_issuer) (const crl_t *this);
-
-       /**
-        * @brief Check if both crls have the same issuer.
-        * 
-        * @param this                          calling object
-        * @param other                         other crl
-        * @return                                      TRUE if the same issuer
-        */
-       bool (*equals_issuer) (const crl_t *this, const crl_t *other);
-
-       /**
-        * @brief Check if ia candidate cert is the issuer of the crl
-        * 
-        * @param this                          calling object
-        * @param issuer                        candidate issuer of the crl
-        * @return                                      TRUE if issuer
-        */
-       bool (*is_issuer) (const crl_t *this, const x509_t *issuer);
-
-       /**
-        * @brief Checks the validity interval of the crl
-        * 
-        * @param this                  calling object
-        * @return                              TRUE if the crl is valid
-        */
-       bool (*is_valid) (const crl_t *this);
-       
-       /**
-        * @brief Checks if this crl is newer (thisUpdate) than the other crl
-        * 
-        * @param this                  calling object
-        * @param other                 other crl object
-        * @return                              TRUE if this was issued more recently than other
-        */
-       bool (*is_newer) (const crl_t *this, const crl_t *other);
-       
-       /**
-        * @brief Check if a crl is trustworthy.
-        * 
-        * @param this                  calling object
-        * @param signer                signer's RSA public key
-        * @return                              TRUE if crl is trustworthy
-        */
-       bool (*verify) (const crl_t *this, const rsa_public_key_t *signer);
-
-       /**
-        * @brief Get the certificate status
-        * 
-        * @param this                  calling object
-        * @param certinfo              certinfo is updated
-        */
-       void (*get_status) (const crl_t *this, certinfo_t *certinfo);
-       
-       /**
-        * @brief Log the info of this CRL to out.
-        *
-        * @param this                  calling object
-        * @param out                   stream to write to
-        * @param utc                   TRUE for UTC, FALSE for local time
-        */
-       void (*list)(crl_t *this, FILE* out, bool utc);
-
-       /**
-        * @brief Write a der-encoded crl to a file
-        * 
-        * @param this                  calling object
-        * @param path                  path where the file is to be stored
-        * @param mask                  file access control rights
-        * @param force                 overwrite the file if it already exists
-        * @return                              TRUE if successfully written
-        */
-       bool (*write_to_file) (const crl_t *this, const char *path, mode_t mask, bool force);
-
-       /**
-        * @brief Destroys the crl.
-        * 
-        * @param this                  crl to destroy
-        */
-       void (*destroy) (crl_t *this);
-};
-
-/**
- * @brief Read a x509 crl from a DER encoded blob.
- * 
- * @param chunk        chunk containing DER encoded data
- * @return                     created crl_t, or NULL if invalid.
- * 
- * @ingroup transforms
- */
-crl_t *crl_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Read a x509 crl from a DER encoded file.
- * 
- * @param filename     file containing DER encoded data
- * @return                     created crl_t, or NULL if invalid.
- * 
- * @ingroup transforms
- */
-crl_t *crl_create_from_file(const char *filename);
-
-#endif /* CRL_H_ */
index 7f62741a792e208069f2d4af498baa98af00b897..69bab02fb69cb6f4ac8b6d3ce5c68c54af726caf 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file crypter.c
- * 
- * @brief Generic constructor for crypter_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 "crypter.h"
 
-#include <crypto/crypters/aes_cbc_crypter.h>
-#include <crypto/crypters/des_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,
@@ -46,23 +36,3 @@ ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CTR, ENCR_DES_IV32,
        "AES_CTR");
 ENUM_END(encryption_algorithm_names, ENCR_AES_CTR);
 
-/*
- * Described in header.
- */
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size)
-{
-       switch (encryption_algorithm)
-       {
-               case ENCR_AES_CBC:
-               {
-                       return (crypter_t*)aes_cbc_crypter_create(key_size);
-               }
-               case ENCR_DES:
-               case ENCR_3DES:
-               {
-                       return (crypter_t*)des_crypter_create(encryption_algorithm);
-               }
-               default:
-                       return NULL;
-       }
-}
index 46d94ce93c0e48644e93cf9417caabdda4134137..c8b38f8fa37bc534de1253f7b15aed30f1702fca 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file crypter.h
- * 
- * @brief Interface crypter_t
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 crypter crypter
+ * @{ @ingroup crypto
  */
 
 #ifndef CRYPTER_H_
@@ -30,21 +30,12 @@ typedef struct crypter_t crypter_t;
 #include <library.h>
 
 /**
- * @brief Encryption algorithm, as in IKEv2 RFC 3.3.2.
- *
- * Currently only the following algorithms are implemented:
- * - ENCR_AES_CBC
- * - ENCR_DES
- * - ENCR_3DES
- *
- * @ingroup crypters
+ * Encryption algorithm, as in IKEv2 RFC 3.3.2.
  */
 enum encryption_algorithm_t {
        ENCR_UNDEFINED = 1024,
        ENCR_DES_IV64 = 1,
-       /** Implemented in class des_crypter_t */
        ENCR_DES = 2,
-       /** Implemented in class des_crypter_t */
        ENCR_3DES = 3,
        ENCR_RC5 = 4,
        ENCR_IDEA = 5,
@@ -53,7 +44,6 @@ enum encryption_algorithm_t {
        ENCR_3IDEA = 8,
        ENCR_DES_IV32 = 9,
        ENCR_NULL = 11,
-       /** Implemented in class aes_cbc_crypter_t */
        ENCR_AES_CBC = 12,
        ENCR_AES_CTR = 13
 };
@@ -64,92 +54,58 @@ enum encryption_algorithm_t {
 extern enum_name_t *encryption_algorithm_names;
 
 /**
- * @brief Generic interface for symmetric encryption algorithms.
- *
- * @b Constructors:
- *  - crypter_create()
- *
- * @ingroup crypters
+ * Generic interface for symmetric encryption algorithms.
  */
 struct crypter_t {
        
        /**
-        * @brief Encrypt a chunk of data and allocate space for the encrypted value.
+        * Encrypt a chunk of data and allocate space for the encrypted value.
         *
-        * @param this                          calling object
-        * @param data                          data to encrypt
-        * @param iv                            initializing vector
-        * @param[out] encrypted        pointer where the encrypted bytes will be written
-        * @return
-        *                                                      - SUCCESS
-        *                                                      - INVALID_ARG if data size not a multiple of block size
+        * @param data                  data to encrypt
+        * @param iv                    initializing vector
+        * @param encrypted             pointer where the encrypted bytes will be written
+        * @return                              SUCCESS, or INVALID_ARG if size invalid
         */
-       status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted);
+       status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv,
+                                                chunk_t *encrypted);
        
        /**
-        * @brief Decrypt a chunk of data and allocate space for the decrypted value.
+        * Decrypt a chunk of data and allocate space for the decrypted value.
         * 
-        * @param this                          calling object
-        * @param data                          data to decrypt
-        * @param iv                            initializing vector
-        * @param[out] encrypted        pointer where the decrypted bytes will be written
-        * @return
-        *                                                      - SUCCESS
-        *                                                      - INVALID_ARG if data size not a multiple of block size
+        * @param data                  data to decrypt
+        * @param iv                    initializing vector
+        * @param encrypted             pointer where the decrypted bytes will be written
+        * @return                              SUCCESS, or INVALID_ARG if invalid
         */
-       status_t (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted);
+       status_t (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv,
+                                                chunk_t *decrypted);
 
        /**
-        * @brief Get the block size of this crypter_t object.
+        * Get the block size of the crypto algorithm.
         * 
-        * @param this                          calling object
         * @return                                      block size in bytes
         */
        size_t (*get_block_size) (crypter_t *this);
 
        /**
-        * @brief Get the key size of this crypter_t object.
+        * Get the key size of the crypto algorithm.
         * 
-        * @param this                          calling object
         * @return                                      key size in bytes
         */
        size_t (*get_key_size) (crypter_t *this);
        
        /**
-        * @brief Set the key for this crypter_t object.
+        * Set the key.
         * 
-        * @param this                          calling object
         * @param key                           key to set
-        * @return
-        *                                                      - SUCCESS
-        *                                                      - INVALID_ARG if key length invalid
+        * @return                                      SUCCESS, or INVALID_ARG if key length invalid
         */
        status_t (*set_key) (crypter_t *this, chunk_t key);
        
        /**
-        * @brief Destroys a crypter_t object.
-        *
-        * @param this                          calling object
+        * Destroys a crypter_t object.
         */
        void (*destroy) (crypter_t *this);
 };
 
-/**
- * @brief Generic constructor for crypter_t objects.
- * 
- * Currently only the following algorithms are implemented:
- * - ENCR_AES_CBC
- * - ENCR_DES
- * - ENCR_3DES
- * 
- * The key_size is ignored for algorithms with fixed key size.
- * 
- * @param encryption_algorithm Algorithm to use for crypter
- * @param key_size                             size of the key in bytes
- * @return
- *                                                             - crypter_t object
- *                                                             - NULL if encryption algorithm/key_size is not supported
- */
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size);
-
-#endif /*CRYPTER_H_*/
+#endif /*CRYPTER_H_ @} */
diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c
new file mode 100644 (file)
index 0000000..1bca84f
--- /dev/null
@@ -0,0 +1,483 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "crypto_factory.h"
+
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+typedef struct crypter_entry_t crypter_entry_t;
+struct crypter_entry_t {
+       /** encryption algorithm */
+       encryption_algorithm_t algo;
+       /** associated constructor */
+       crypter_constructor_t create;
+};
+
+typedef struct signer_entry_t signer_entry_t;
+struct signer_entry_t {
+       /** integrity algorithm */
+       integrity_algorithm_t algo;
+       /** associated constructor */
+       signer_constructor_t create;
+};
+
+typedef struct hasher_entry_t hasher_entry_t;
+struct hasher_entry_t {
+       /** hash algorithm */
+       hash_algorithm_t algo;
+       /** associated constructor */
+       hasher_constructor_t create;
+};
+
+typedef struct prf_entry_t prf_entry_t;
+struct prf_entry_t {
+       /** hash algorithm */
+       pseudo_random_function_t algo;
+       /** associated constructor */
+       prf_constructor_t create;
+};
+
+typedef struct dh_entry_t dh_entry_t;
+struct dh_entry_t {
+       /** hash algorithm */
+       diffie_hellman_group_t group;
+       /** associated constructor */
+       dh_constructor_t create;
+};
+
+typedef struct private_crypto_factory_t private_crypto_factory_t;
+
+/**
+ * private data of crypto_factory
+ */
+struct private_crypto_factory_t {
+
+       /**
+        * public functions
+        */
+       crypto_factory_t public;
+       
+       /**
+        * registered crypters, as crypter_entry_t
+        */
+       linked_list_t *crypters;
+       
+       /**
+        * registered signers, as signer_entry_t
+        */
+       linked_list_t *signers;
+       
+       /**
+        * registered hashers, as hasher_entry_t
+        */
+       linked_list_t *hashers;
+       
+       /**
+        * registered perfs, as prf_entry_t
+        */
+       linked_list_t *prfs;
+       
+       /**
+        * registered diffie hellman, as dh_entry_t
+        */
+       linked_list_t *dhs;
+       
+       /**
+        * mutex to lock access to modules
+        */
+       mutex_t *mutex;
+};
+
+/**
+ * Implementation of crypto_factory_t.create_crypter.
+ */
+static crypter_t* create_crypter(private_crypto_factory_t *this,
+                                                                encryption_algorithm_t algo, size_t key_size)
+{
+       enumerator_t *enumerator;
+       crypter_entry_t *entry;
+       crypter_t *crypter = NULL;
+
+       this->mutex->lock(this->mutex);
+       enumerator = this->crypters->create_enumerator(this->crypters);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->algo == algo)
+               {
+                       crypter = entry->create(algo, key_size);
+                       if (crypter)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return crypter;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_signer.
+ */
+static signer_t* create_signer(private_crypto_factory_t *this,
+                                                          integrity_algorithm_t algo)
+{
+       enumerator_t *enumerator;
+       signer_entry_t *entry;
+       signer_t *signer = NULL;
+
+       this->mutex->lock(this->mutex);
+       enumerator = this->signers->create_enumerator(this->signers);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->algo == algo)
+               {
+                       signer = entry->create(algo);
+                       if (signer)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+
+       return signer;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_hasher.
+ */
+static hasher_t* create_hasher(private_crypto_factory_t *this,
+                                                          hash_algorithm_t algo)
+{
+       enumerator_t *enumerator;
+       hasher_entry_t *entry;
+       hasher_t *hasher = NULL;
+
+       this->mutex->lock(this->mutex);
+       enumerator = this->hashers->create_enumerator(this->hashers);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (algo == HASH_PREFERRED || entry->algo == algo)
+               {
+                       hasher = entry->create(entry->algo);
+                       if (hasher)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return hasher;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_prf.
+ */
+static prf_t* create_prf(private_crypto_factory_t *this,
+                                                pseudo_random_function_t algo)
+{
+       enumerator_t *enumerator;
+       prf_entry_t *entry;
+       prf_t *prf = NULL;
+
+       this->mutex->lock(this->mutex);
+       enumerator = this->prfs->create_enumerator(this->prfs);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->algo == algo)
+               {
+                       prf = entry->create(algo);
+                       if (prf)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return prf;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_dh.
+ */
+static diffie_hellman_t* create_dh(private_crypto_factory_t *this,
+                                                                  diffie_hellman_group_t group)
+{
+       enumerator_t *enumerator;
+       dh_entry_t *entry;
+       diffie_hellman_t *diffie_hellman = NULL;
+
+       this->mutex->lock(this->mutex);
+       enumerator = this->dhs->create_enumerator(this->dhs);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->group == group)
+               {
+                       diffie_hellman = entry->create(group);
+                       if (diffie_hellman)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return diffie_hellman;
+}
+
+/**
+ * Implementation of crypto_factory_t.add_crypter.
+ */
+static void add_crypter(private_crypto_factory_t *this,
+                                               encryption_algorithm_t algo,
+                                               crypter_constructor_t create)
+{
+       crypter_entry_t *entry = malloc_thing(crypter_entry_t);
+       
+       entry->algo = algo;
+       entry->create = create;
+       this->mutex->lock(this->mutex);
+       this->crypters->insert_last(this->crypters, entry);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_crypter.
+ */
+static void remove_crypter(private_crypto_factory_t *this,
+                                                  crypter_constructor_t create)
+{
+       crypter_entry_t *entry;
+       enumerator_t *enumerator;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->crypters->create_enumerator(this->crypters);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create == create)
+               {
+                       this->crypters->remove_at(this->crypters, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_signer.
+ */
+static void add_signer(private_crypto_factory_t *this,
+                                          integrity_algorithm_t algo, signer_constructor_t create)
+{
+       signer_entry_t *entry = malloc_thing(signer_entry_t);
+       
+       entry->algo = algo;
+       entry->create = create;
+       this->mutex->lock(this->mutex);
+       this->signers->insert_last(this->signers, entry);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_signer.
+ */
+static void remove_signer(private_crypto_factory_t *this,
+                                                 signer_constructor_t create)
+{
+       signer_entry_t *entry;
+       enumerator_t *enumerator;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->signers->create_enumerator(this->signers);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create == create)
+               {
+                       this->signers->remove_at(this->signers, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_hasher.
+ */
+static void add_hasher(private_crypto_factory_t *this, hash_algorithm_t algo,
+                                          hasher_constructor_t create)
+{
+       hasher_entry_t *entry = malloc_thing(hasher_entry_t);
+       
+       entry->algo = algo;
+       entry->create = create;
+       this->mutex->lock(this->mutex);
+       this->hashers->insert_last(this->hashers, entry);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_hasher.
+ */
+static void remove_hasher(private_crypto_factory_t *this,
+                                                 hasher_constructor_t create)
+{
+       hasher_entry_t *entry;
+       enumerator_t *enumerator;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->hashers->create_enumerator(this->hashers);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create == create)
+               {
+                       this->hashers->remove_at(this->hashers, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_prf.
+ */
+static void add_prf(private_crypto_factory_t *this,
+                                       pseudo_random_function_t algo, prf_constructor_t create)
+{
+       prf_entry_t *entry = malloc_thing(prf_entry_t);
+       
+       entry->algo = algo;
+       entry->create = create;
+       this->mutex->lock(this->mutex);
+       this->prfs->insert_last(this->prfs, entry);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_prf.
+ */
+static void remove_prf(private_crypto_factory_t *this, prf_constructor_t create)
+{
+       prf_entry_t *entry;
+       enumerator_t *enumerator;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->prfs->create_enumerator(this->prfs);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create == create)
+               {
+                       this->prfs->remove_at(this->prfs, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_dh.
+ */
+static void add_dh(private_crypto_factory_t *this, diffie_hellman_group_t group,
+                                  dh_constructor_t create)
+{
+       dh_entry_t *entry = malloc_thing(dh_entry_t);
+       
+       entry->group = group;
+       entry->create = create;
+       this->mutex->lock(this->mutex);
+       this->dhs->insert_last(this->dhs, entry);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_dh.
+ */
+static void remove_dh(private_crypto_factory_t *this, dh_constructor_t create)
+{
+       dh_entry_t *entry;
+       enumerator_t *enumerator;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->dhs->create_enumerator(this->dhs);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create == create)
+               {
+                       this->dhs->remove_at(this->dhs, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.destroy
+ */
+static void destroy(private_crypto_factory_t *this)
+{
+       this->crypters->destroy_function(this->crypters, free);
+       this->signers->destroy_function(this->signers, free);
+       this->hashers->destroy_function(this->hashers, free);
+       this->prfs->destroy_function(this->prfs, free);
+       this->dhs->destroy_function(this->dhs, free);
+       this->mutex->destroy(this->mutex);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+crypto_factory_t *crypto_factory_create()
+{
+       private_crypto_factory_t *this = malloc_thing(private_crypto_factory_t);
+       
+       this->public.create_crypter = (crypter_t*(*)(crypto_factory_t*, encryption_algorithm_t, size_t))create_crypter;
+       this->public.create_signer = (signer_t*(*)(crypto_factory_t*, integrity_algorithm_t))create_signer;
+       this->public.create_hasher = (hasher_t*(*)(crypto_factory_t*, hash_algorithm_t))create_hasher;
+       this->public.create_prf = (prf_t*(*)(crypto_factory_t*, pseudo_random_function_t))create_prf;
+       this->public.create_dh = (diffie_hellman_t*(*)(crypto_factory_t*, diffie_hellman_group_t group))create_dh;
+       this->public.add_crypter = (void(*)(crypto_factory_t*, encryption_algorithm_t algo, crypter_constructor_t create))add_crypter;
+       this->public.remove_crypter = (void(*)(crypto_factory_t*, crypter_constructor_t create))remove_crypter;
+       this->public.add_signer = (void(*)(crypto_factory_t*, integrity_algorithm_t algo, signer_constructor_t create))add_signer;
+       this->public.remove_signer = (void(*)(crypto_factory_t*, signer_constructor_t create))remove_signer;
+       this->public.add_hasher = (void(*)(crypto_factory_t*, hash_algorithm_t algo, hasher_constructor_t create))add_hasher;
+       this->public.remove_hasher = (void(*)(crypto_factory_t*, hasher_constructor_t create))remove_hasher;
+       this->public.add_prf = (void(*)(crypto_factory_t*, pseudo_random_function_t algo, prf_constructor_t create))add_prf;
+       this->public.remove_prf = (void(*)(crypto_factory_t*, prf_constructor_t create))remove_prf;
+       this->public.add_dh = (void(*)(crypto_factory_t*, diffie_hellman_group_t algo, dh_constructor_t create))add_dh;
+       this->public.remove_dh = (void(*)(crypto_factory_t*, dh_constructor_t create))remove_dh;
+       this->public.destroy = (void(*)(crypto_factory_t*))destroy;
+       
+       this->crypters = linked_list_create();
+       this->signers = linked_list_create();
+       this->hashers = linked_list_create();
+       this->prfs = linked_list_create();
+       this->dhs = linked_list_create();
+       this->mutex = mutex_create(MUTEX_RECURSIVE);
+       
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/crypto/crypto_factory.h b/src/libstrongswan/crypto/crypto_factory.h
new file mode 100644 (file)
index 0000000..c8c2bcc
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup crypto_factory crypto_factory
+ * @{ @ingroup crypto
+ */
+
+#ifndef CRYPTO_FACTORY_H_
+#define CRYPTO_FACTORY_H_
+
+typedef struct crypto_factory_t crypto_factory_t;
+
+#include <library.h>
+#include <crypto/crypters/crypter.h>
+#include <crypto/signers/signer.h>
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
+#include <crypto/diffie_hellman.h>
+
+/**
+ * Constructor function for crypters
+ */
+typedef crypter_t* (*crypter_constructor_t)(encryption_algorithm_t algo,
+                                                                                       size_t key_size);
+/**
+ * Constructor function for signers
+ */
+typedef signer_t* (*signer_constructor_t)(integrity_algorithm_t algo);
+
+/**
+ * Constructor function for hashers
+ */
+typedef hasher_t* (*hasher_constructor_t)(hash_algorithm_t algo);
+
+/**
+ * Constructor function for pseudo random fucntions
+ */
+typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo);
+
+/**
+ * Constructor function for diffie hellman
+ */
+typedef diffie_hellman_t* (*dh_constructor_t)(diffie_hellman_group_t group);
+
+/**
+ * Handles crypto modules and creates instances.
+ */
+struct crypto_factory_t {
+
+       /**
+        * Create a crypter instance.
+        *
+        * @param algo                  encryption algorithm
+        * @param key_size              length of the key in bytes
+        * @return                              crypter_t instance, NULL if not supported
+        */
+       crypter_t* (*create_crypter)(crypto_factory_t *this,
+                                                                encryption_algorithm_t algo, size_t key_size);
+       
+       /**
+        * Create a symmetric signer instance.
+        *
+        * @param algo                  MAC algorithm to use
+        * @return                              signer_t instance, NULL if not supported
+        */
+       signer_t* (*create_signer)(crypto_factory_t *this,
+                                                          integrity_algorithm_t algo);
+
+       /**
+        * Create a hasher instance.
+        *
+        * @param algo                  hash algorithm
+        * @return                              hasher_t instance, NULL if not supported
+        */
+       hasher_t* (*create_hasher)(crypto_factory_t *this, hash_algorithm_t algo);
+       
+       /**
+        * Create a pseudo random function instance.
+        *
+        * @param algo                  PRF algorithm to use
+        * @return                              prf_t instance, NULL if not supported
+        */
+       prf_t* (*create_prf)(crypto_factory_t *this, pseudo_random_function_t algo);
+       
+       /**
+        * Create a diffie hellman instance.
+        *
+        * @param group                 diffie hellman group
+        * @return                              diffie_hellman_t instance, NULL if not supported
+        */
+       diffie_hellman_t* (*create_dh)(crypto_factory_t *this,
+                                                                  diffie_hellman_group_t group);
+       
+       /**
+        * Register a crypter constructor.
+        *
+        * @param algo                  algorithm to constructor
+        * @param create                constructor function for that algorithm
+        * @return
+        */
+       void (*add_crypter)(crypto_factory_t *this, encryption_algorithm_t algo,
+                                               crypter_constructor_t create);
+       
+       /**
+        * Unregister a crypter constructor.
+        *
+        * @param create                constructor function to unregister
+        */
+       void (*remove_crypter)(crypto_factory_t *this, crypter_constructor_t create);
+       
+       /**
+        * Register a signer constructor.
+        *
+        * @param algo                  algorithm to constructor
+        * @param create                constructor function for that algorithm
+        * @return
+        */
+       void (*add_signer)(crypto_factory_t *this, integrity_algorithm_t algo,
+                                          signer_constructor_t create);
+       
+       /**
+        * Unregister a signer constructor.
+        *
+        * @param create                constructor function to unregister
+        */
+       void (*remove_signer)(crypto_factory_t *this, signer_constructor_t create);
+       
+       /**
+        * Register a hasher constructor.
+        *
+        * The first added hasher is the preferred hasher returned on
+        * create_hasher(HASH_PREFERRED).
+        *
+        * @param algo                  algorithm to constructor
+        * @param create                constructor function for that algorithm
+        * @return
+        */
+       void (*add_hasher)(crypto_factory_t *this, hash_algorithm_t algo,
+                                          hasher_constructor_t create);
+       
+       /**
+        * Unregister a hasher constructor.
+        *
+        * @param create                constructor function to unregister
+        */
+       void (*remove_hasher)(crypto_factory_t *this, hasher_constructor_t create);
+       
+       /**
+        * Register a prf constructor.
+        *
+        * @param algo                  algorithm to constructor
+        * @param create                constructor function for that algorithm
+        * @return
+        */
+       void (*add_prf)(crypto_factory_t *this, pseudo_random_function_t algo,
+                                       prf_constructor_t create);
+       
+       /**
+        * Unregister a prf constructor.
+        *
+        * @param create                constructor function to unregister
+        */
+       void (*remove_prf)(crypto_factory_t *this, prf_constructor_t create);
+       
+       /**
+        * Register a diffie hellman constructor.
+        *
+        * @param group                 dh group to constructor
+        * @param create                constructor function for that algorithm
+        * @return
+        */
+       void (*add_dh)(crypto_factory_t *this, diffie_hellman_group_t group,
+                                  dh_constructor_t create);
+       
+       /**
+        * Unregister a diffie hellman constructor.
+        *
+        * @param create                constructor function to unregister
+        */
+       void (*remove_dh)(crypto_factory_t *this, dh_constructor_t create);
+       
+       /**
+     * Destroy a crypto_factory instance.
+     */
+    void (*destroy)(crypto_factory_t *this);
+};
+
+/**
+ * Create a crypto_factory instance.
+ */
+crypto_factory_t *crypto_factory_create();
+
+#endif /* CRYPTO_FACTORY_H_ @}*/
index 605892e87767d6d49cb832659faa748934c97a21..92270872027febfa4c82a488c113089605f57966 100644 (file)
@@ -1,14 +1,5 @@
-/**
- * @file diffie_hellman.c
- * 
- * @brief Implementation of diffie_hellman_t.
- * 
- */
-
 /*
- * Copyright (C) 1998-2002  D. Hugh Redelmeier.
- * Copyright (C) 1999, 2000, 2001  Henry Spencer.
- * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * WITHOUT ANY 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 <gmp.h>
-
 #include "diffie_hellman.h"
 
-#include <utils/randomizer.h>
-#include <debug.h>
-
 ENUM_BEGIN(diffie_hellman_group_names, MODP_NONE, MODP_1024_BIT,
        "MODP_NONE",
        "MODP_768_BIT",
@@ -44,546 +32,3 @@ ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, MODP_8192_BIT, MODP_1536_BI
        "MODP_8192_BIT");
 ENUM_END(diffie_hellman_group_names, MODP_8192_BIT);
 
-
-/**
- * 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 {
-       /**
-        * Group number as it is defined in file transform_substructure.h.
-        */
-       diffie_hellman_group_t group;
-       
-       /**
-        * Pointer to first byte of modulus (network order).
-        */
-       u_int8_t *modulus;
-       
-       /* 
-        * Length of modulus in bytes.
-        */     
-       size_t modulus_len;
-       
-       /* 
-        * Generator value.
-        */     
-       u_int16_t generator;
-};
-
-/**
- * All supported modulus values.
- */
-static modulus_entry_t modulus_entries[] = {
-       {MODP_768_BIT, group1_modulus, sizeof(group1_modulus), 2},
-       {MODP_1024_BIT, group2_modulus, sizeof(group2_modulus), 2},
-       {MODP_1536_BIT, group5_modulus, sizeof(group5_modulus), 2},
-       {MODP_2048_BIT, group14_modulus, sizeof(group14_modulus), 2},
-       {MODP_3072_BIT, group15_modulus, sizeof(group15_modulus), 2},
-       {MODP_4096_BIT, group16_modulus, sizeof(group16_modulus), 2},
-       {MODP_6144_BIT, group17_modulus, sizeof(group17_modulus), 2},
-       {MODP_8192_BIT, group18_modulus, sizeof(group18_modulus), 2},
-};
-
-typedef struct private_diffie_hellman_t private_diffie_hellman_t;
-
-/**
- * Private data of an diffie_hellman_t object.
- * 
- */
-struct private_diffie_hellman_t {
-       /**
-        * Public diffie_hellman_t interface.
-        */
-       diffie_hellman_t public;
-       
-       /**
-        * Diffie Hellman group number.
-        */
-       u_int16_t group;
-       
-       /* 
-        * Generator value.
-        */     
-       mpz_t g;
-
-       /**
-        * My private value.
-        */
-       mpz_t xa;
-       
-       /**
-        * My public value.
-        */
-       mpz_t ya;
-
-       /**
-        * Other public value.
-        */     
-       mpz_t yb;
-       
-       /**
-        * Shared secret.
-        */     
-       mpz_t zz;
-
-       /**
-        * Modulus.
-        */
-       mpz_t p;
-       
-       /**
-        * Modulus length.
-        */
-       size_t p_len;
-
-       /**
-        * True if shared secret is computed and stored in my_public_value.
-        */
-       bool computed;
-};
-
-/**
- * Implementation of diffie_hellman_t.set_other_public_value.
- */
-static void set_other_public_value(private_diffie_hellman_t *this, chunk_t value)
-{
-       mpz_t p_min_1;
-       
-       mpz_init(p_min_1);
-       mpz_sub_ui(p_min_1, this->p, 1);
-       
-       mpz_import(this->yb, value.len, 1, 1, 1, 0, value.ptr);
-       
-       /* 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 (mpz_cmp_ui(this->yb, 1) > 0 ||
-               mpz_cmp(this->yb, p_min_1) < 0)
-       {
-#ifdef EXTENDED_DH_TEST
-               /* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */
-               mpz_t q, one;
-               
-               mpz_init(q);
-               mpz_init(one);
-               mpz_fdiv_q_2exp(q, p_min_1, 1);
-               mpz_powm(one, this->yb, q, this->p);
-               mpz_clear(q);
-               if (mpz_cmp_ui(one, 1) == 0)
-               {
-                       mpz_powm(this->zz, this->yb, this->xa, this->p);
-                       this->computed = TRUE;
-               }
-               else
-               {
-                       DBG1("public DH value verification failed: y ^ q mod p != 1");
-               }
-               mpz_clear(one);
-#else
-               mpz_powm(this->zz, this->yb, this->xa, this->p);
-               this->computed = TRUE;
-#endif
-       }
-       else
-       {
-               DBG1("public DH value verification failed: y < 2 || y > p - 1 ");
-       }
-       mpz_clear(p_min_1);
-}
-
-/**
- * Implementation of diffie_hellman_t.get_other_public_value.
- */
-static status_t get_other_public_value(private_diffie_hellman_t *this, 
-                                                                          chunk_t *value)
-{
-       if (!this->computed)
-       {
-               return FAILED;
-       }
-       value->len = this->p_len;
-    value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->yb);
-       return SUCCESS;
-}
-
-/**
- * Implementation of diffie_hellman_t.get_my_public_value.
- */
-static void get_my_public_value(private_diffie_hellman_t *this,chunk_t *value)
-{
-       value->len = this->p_len;
-    value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->ya);
-}
-
-/**
- * Implementation of diffie_hellman_t.get_shared_secret.
- */
-static status_t get_shared_secret(private_diffie_hellman_t *this, chunk_t *secret)
-{
-       if (!this->computed)
-       {
-               return FAILED;
-       }
-       secret->len = this->p_len;
-    secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz);
-       return SUCCESS;
-}
-
-/**
- * Implementation of diffie_hellman_t.get_dh_group.
- */
-static diffie_hellman_group_t get_dh_group(private_diffie_hellman_t *this)
-{
-       return this->group;
-}
-
-/**
- * Lookup the modulus in modulo table
- */
-static status_t set_modulus(private_diffie_hellman_t *this)
-{
-       int i;
-       status_t status = NOT_FOUND;
-       
-       for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
-       {
-               if (modulus_entries[i].group == this->group)
-               {
-                       chunk_t chunk;
-                       chunk.ptr = modulus_entries[i].modulus;
-                       chunk.len = modulus_entries[i].modulus_len;
-                       mpz_import(this->p, chunk.len, 1, 1, 1, 0, chunk.ptr);
-                       this->p_len = chunk.len;
-                       mpz_set_ui(this->g, modulus_entries[i].generator);
-                       status = SUCCESS;
-                       break;
-               }
-       }
-       return status;
-}
-
-/**
- * Implementation of diffie_hellman_t.destroy.
- */
-static void destroy(private_diffie_hellman_t *this)
-{
-       mpz_clear(this->p);
-       mpz_clear(this->xa);
-       mpz_clear(this->ya);
-       mpz_clear(this->yb);
-       mpz_clear(this->zz);
-       mpz_clear(this->g);
-       free(this);
-}
-
-/*
- * Described in header.
- */
-diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group)
-{
-       private_diffie_hellman_t *this = malloc_thing(private_diffie_hellman_t);
-       randomizer_t *randomizer;
-       chunk_t random;
-       status_t status;
-
-       /* public functions */
-       this->public.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
-       this->public.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
-       this->public.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
-       this->public.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
-       this->public.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
-       this->public.destroy = (void (*)(diffie_hellman_t *)) destroy;
-       
-       /* private variables */
-       this->group = group;
-       mpz_init(this->p);
-       mpz_init(this->yb);
-       mpz_init(this->ya);
-       mpz_init(this->xa);
-       mpz_init(this->zz);
-       mpz_init(this->g);
-       
-       this->computed = FALSE;
-               
-       /* find a modulus according to group */ 
-       if (set_modulus(this) != SUCCESS)
-       {
-               destroy(this);
-               return NULL;
-       }
-       randomizer = randomizer_create();
-       status = randomizer->allocate_pseudo_random_bytes(
-                                                                                       randomizer, this->p_len, &random);
-       randomizer->destroy(randomizer);
-       if (status != SUCCESS)
-       {
-               destroy(this);
-               return NULL;
-       }
-       mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr);
-       chunk_free(&random);
-       
-       mpz_powm(this->ya, this->g, this->xa, this->p);
-       
-       return &this->public;
-}
-
index 8cd06d60eb3cb13f6c23cc55e1b562905b96085f..07e475b477ee85fe114f352e6336322153d957ac 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file diffie_hellman.h
- * 
- * @brief Interface of diffie_hellman_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2007 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 diffie_hellman diffie_hellman
+ * @{ @ingroup crypto
  */
 
 #ifndef DIFFIE_HELLMAN_H_
@@ -30,13 +30,10 @@ typedef struct diffie_hellman_t diffie_hellman_t;
 #include <library.h>
 
 /**
- * @brief Diffie-Hellman group.
+ * Diffie-Hellman group.
  *
  * The modulus (or group) to use for a Diffie-Hellman calculation.
- *
  * See IKEv2 RFC 3.3.2 and RFC 3526.
- *
- * @ingroup crypto
  */
 enum diffie_hellman_group_t {
        MODP_NONE = 0,
@@ -56,89 +53,60 @@ enum diffie_hellman_group_t {
 extern enum_name_t *diffie_hellman_group_names;
 
 /**
- * @brief Implementation of the Diffie-Hellman algorithm, as in RFC2631.
- * 
- * @b Constructors:
- *  - diffie_hellman_create()
- * 
- * @ingroup crypto
+ * Implementation of the Diffie-Hellman algorithm, as in RFC2631.
  */
 struct diffie_hellman_t {
                
        /**
-        * @brief Returns the shared secret of this diffie hellman exchange.
+        * Returns the shared secret of this diffie hellman exchange.
         *      
         * Space for returned secret is allocated and must be 
         * freed by the caller.
         * 
-        * @param this          calling object
         * @param secret        shared secret will be written into this chunk
-        * @return                              
-        *                                      - SUCCESS
-        *                                      - FAILED if not both DH values are set
+        * @return                      SUCCESS, FAILED if not both DH values are set
         */
        status_t (*get_shared_secret) (diffie_hellman_t *this, chunk_t *secret);
        
        /**
-        * @brief Sets the public value of partner.
+        * Sets the public value of partner.
         *      
         * Chunk gets cloned and can be destroyed afterwards.
         * 
-        * @param this          calling object
         * @param value         public value of partner
         */
        void (*set_other_public_value) (diffie_hellman_t *this, chunk_t value);
        
        /**
-        * @brief Gets the public value of partner.
+        * Gets the public value of partner.
         *      
         * Space for returned chunk is allocated and must be freed by the caller.
         * 
-        * @param this          calling object
         * @param value         public value of partner is stored at this location
-        * @return                              
-        *                                      - SUCCESS
-        *                                      - FAILED if other public value not set
+        * @return                      SUCCESS, FAILED if other public value not set
         */
        status_t (*get_other_public_value) (diffie_hellman_t *this, chunk_t *value);
        
        /**
-        * @brief Gets the own public value to transmit.
+        * Gets the own public value to transmit.
         *      
         * Space for returned chunk is allocated and must be freed by the caller.
         * 
-        * @param this          calling object
         * @param value         public value of caller is stored at this location
         */
        void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value);
        
        /**
-        * @brief Get the DH group used.
+        * Get the DH group used.
         * 
-        * @param this          calling object
         * @return                      DH group set in construction
         */
        diffie_hellman_group_t (*get_dh_group) (diffie_hellman_t *this);
 
        /**
-        * @brief Destroys an diffie_hellman_t object.
-        *
-        * @param this          diffie_hellman_t object to destroy
+        * Destroys an diffie_hellman_t object.
         */
        void (*destroy) (diffie_hellman_t *this);
 };
 
-/**
- * @brief Creates a new diffie_hellman_t object.
- * 
- * @param group                        Diffie Hellman group number to use
- * @return
- *                                             - diffie_hellman_t object
- *                                             - NULL if dh group not supported
- * 
- * @ingroup crypto
- */
-diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group);
-
-#endif /*DIFFIE_HELLMAN_H_*/
-
+#endif /*DIFFIE_HELLMAN_H_ @} */
index d8c6ff94c749fb7595bd91c034e08aa1ae0bff3d..ea4b4b08b8e477c1acce080ff8b957ecff68faeb 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file hasher.c
- * 
- * @brief Generic constructor for hasher_t.
- * 
- */
-
 /*
  * Copyright (C) 2005 Jan Hutter
  * Copyright (C) 2005-2006 Martin Willi
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
  */
 
-
 #include "hasher.h"
 
 #include <asn1/oid.h>
-#include <crypto/hashers/sha1_hasher.h>
-#include <crypto/hashers/sha2_hasher.h>
-#include <crypto/hashers/md5_hasher.h>
-
 
 ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
        "HASH_UNKNOWN",
+       "HASH_PREFERRED",
        "HASH_MD2",
        "HASH_MD5",
        "HASH_SHA1",
+       "HASH_SHA1_NOFINAL",
        "HASH_SHA256",
        "HASH_SHA384",
        "HASH_SHA512"
 );
 
-/*
- * Described in header.
- */
-hasher_t *hasher_create(hash_algorithm_t hash_algorithm)
-{
-       switch (hash_algorithm)
-       {
-               case HASH_SHA1:
-               {
-                       return (hasher_t*)sha1_hasher_create();
-               }
-               case HASH_SHA256:
-               case HASH_SHA384:
-               case HASH_SHA512:
-               {
-                       return (hasher_t*)sha2_hasher_create(hash_algorithm);
-               }
-               case HASH_MD5:
-               {
-                       return (hasher_t*)md5_hasher_create();
-               }
-               default:
-                       return NULL;
-       }
-}
-
 /*
  * Described in header.
  */
 hash_algorithm_t hasher_algorithm_from_oid(int oid)
 {
-       hash_algorithm_t algorithm;
-
        switch (oid)
        {
                case OID_MD2:
                case OID_MD2_WITH_RSA:
-                       algorithm = HASH_MD2;
-                       break;
+                       return HASH_MD2;
                case OID_MD5:
                case OID_MD5_WITH_RSA:
-                       algorithm = HASH_MD5;
-                       break;
+                       return HASH_MD5;
                case OID_SHA1:
                case OID_SHA1_WITH_RSA:
-                       algorithm = HASH_SHA1;
-                       break;
+                       return HASH_SHA1;
                case OID_SHA256:
                case OID_SHA256_WITH_RSA:
-                       algorithm = HASH_SHA256;
-                       break;
+                       return HASH_SHA256;
                case OID_SHA384:
                case OID_SHA384_WITH_RSA:
-                       algorithm = HASH_SHA384;
-                       break;
+                       return HASH_SHA384;
                case OID_SHA512:
                case OID_SHA512_WITH_RSA:
-                       algorithm = HASH_SHA512;
-                       break;
+                       return HASH_SHA512;
                default:
-                       algorithm = HASH_UNKNOWN;
+                       return HASH_UNKNOWN;
        }
-       return algorithm;
 }
 
 /*
index d6604b883de8c703f8664b4cd1bd8110501e00c0..4aa4ba357b0cd0dae81c68344efaec19459635ee 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file hasher.h
- * 
- * @brief Interface hasher_t.
- * 
- */
-
 /*
  * Copyright (C) 2005 Jan Hutter
  * Copyright (C) 2005-2006 Martin Willi
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
+ */
+/**
+ * @defgroup traffic_selector traffic_selector
+ * @{ @ingroup config
  */
 
 #ifndef HASHER_H_
@@ -33,30 +31,21 @@ typedef struct hasher_t hasher_t;
 #include <library.h>
 
 /**
- * @brief Algorithms to use for hashing.
- *
- * Currently only the following algorithms are implemented:
- * - HASH_MD5
- * - HASH_SHA1
- * - HASH_SHA256
- * - HASH_SHA384
- * - HASH_SHA512
- *
- * @ingroup hashers
+ * Algorithms to use for hashing.
  */
 enum hash_algorithm_t {
-       HASH_UNKNOWN = 0,
-       HASH_MD2 =     1,
-       /** Implemented in class md5_hasher_t */
-       HASH_MD5 =     2,
-       /** Implemented in class sha1_hasher_t */
-       HASH_SHA1 =    3,
-       /** Implemented in class sha2_hasher_t */
-       HASH_SHA256 =  4,
-       /** Implemented in class sha2_hasher_t */
-       HASH_SHA384 =  5,
-       /** Implemented in class sha2_hasher_t */
-       HASH_SHA512 =  6,
+       /** not specified hash function */
+       HASH_UNKNOWN            = 0,
+       /** preferred hash function, general purpose */
+       HASH_PREFERRED          = 1,
+       HASH_MD2                        = 2,
+       HASH_MD5                        = 3,
+       HASH_SHA1                       = 4,
+       /** special SHA1 which does not run SHA1Final, but copies the state */
+       HASH_SHA1_NOFINAL       = 5,
+       HASH_SHA256             = 6,
+       HASH_SHA384             = 7,
+       HASH_SHA512             = 8,
 };
 
 #define HASH_SIZE_MD2          16
@@ -65,7 +54,6 @@ enum hash_algorithm_t {
 #define HASH_SIZE_SHA256       32
 #define HASH_SIZE_SHA384       48
 #define HASH_SIZE_SHA512       64
-#define HASH_SIZE_MAX          64
 
 /**
  * enum names for hash_algorithm_t.
@@ -73,16 +61,11 @@ enum hash_algorithm_t {
 extern enum_name_t *hash_algorithm_names;
 
 /**
- * @brief Generic interface for all hash functions.
- * 
- * @b Constructors:
- *  - hasher_create()
- * 
- * @ingroup hashers
+ * Generic interface for all hash functions.
  */
 struct hasher_t {
        /**
-        * @brief Hash data and write it in the buffer.
+        * Hash data and write it in the buffer.
         * 
         * If the parameter hash is NULL, no result is written back
         * and more data can be appended to already hashed data.
@@ -91,108 +74,63 @@ struct hasher_t {
         * The hash output parameter must hold at least
         * hash_t.get_block_size() bytes.
         * 
-        * @param this                  calling object
-        * @param data                  data to hash
-        * @param[out] hash             pointer where the hash will be written
+        * @param data          data to hash
+        * @param hash          pointer where the hash will be written
         */
        void (*get_hash) (hasher_t *this, chunk_t data, u_int8_t *hash);
        
        /**
-        * @brief Hash data and allocate space for the hash.
+        * Hash data and allocate space for the hash.
         * 
         * If the parameter hash is NULL, no result is written back
         * and more data can be appended to already hashed data.
         * If not, the result is written back and the hasher is reset.
         * 
-        * @param this                  calling object
-        * @param data                  chunk with data to hash
-        * @param[out] hash             chunk which will hold allocated hash
+        * @param data          chunk with data to hash
+        * @param hash          chunk which will hold allocated hash
         */
        void (*allocate_hash) (hasher_t *this, chunk_t data, chunk_t *hash);
        
        /**
-        * @brief Get the size of the resulting hash.
+        * Get the size of the resulting hash.
         * 
-        * @param this                  calling object
-        * @return                              hash size in bytes
+        * @return                      hash size in bytes
         */
        size_t (*get_hash_size) (hasher_t *this);
        
        /**
-        * @brief Resets the hashers state.
-        * 
-        * @param this                  calling object
+        * Resets the hashers state.
         */
        void (*reset) (hasher_t *this);
        
        /**
-        * @brief Get the state of the hasher.
-        *
-        * A hasher stores internal state information. This state may be
-        * manipulated to include a "seed" into the hashing operation. It used by
-        * some exotic protocols (such as AKA).
-        * The data pointed by chunk may be manipulated, but not replaced nor freed.
-        * This is more a hack than a feature. The hasher's state may be byte
-        * order dependant; use with care.
-        *
-        * @param this                  calling object
-        */
-       chunk_t (*get_state) (hasher_t *this);
-       
-       /**
-        * @brief Destroys a hasher object.
-        *
-        * @param this                  calling object
+        * Destroys a hasher object.
         */
        void (*destroy) (hasher_t *this);
 };
 
 /**
- * @brief Generic interface to create a hasher_t.
+ * Conversion of ASN.1 OID to hash algorithm.
  * 
- * @param hash_algorithm       Algorithm to use for hashing
- * @return
- *                                                     - hasher_t object
- *                                                     - NULL if algorithm not supported
- * 
- * @ingroup hashers
- */
-hasher_t *hasher_create(hash_algorithm_t hash_algorithm);
-
-/**
- * @brief Conversion of ASN.1 OID to hash algorithm.
- * 
- * @param oid                          ASN.1 OID
- * @return
- *                                                     - hash algorithm
- *                                                     - HASH_UNKNOWN if OID unsuported
- * 
- * @ingroup hashers
+ * @param oid                  ASN.1 OID
+ * @return                             hash algorithm, HASH_UNKNOWN if OID unsuported
  */
 hash_algorithm_t hasher_algorithm_from_oid(int oid);
 
 /**
- * @brief Conversion of hash algorithm into ASN.1 OID.
+ * Conversion of hash algorithm into ASN.1 OID.
  * 
- * @param alg                          hash algorithm
- * @return
- *                                                     - ASN.1 hash OID if known hash algorithm
- *                                                     - OID_UNKNOW
- * 
- * @ingroup hashers
+ * @param alg                  hash algorithm
+ * @return                             ASN.1 OID, or OID_UNKNOW
  */
 int hasher_algorithm_to_oid(hash_algorithm_t alg);
 
 /**
- * @brief Conversion of hash signature algorithm into ASN.1 OID.
- * 
- * @param alg                          hash algorithm
- * @return
- *                                                     - ASN.1 signature OID if known hash algorithm
- *                                                     - OID_UNKNOW
+ * Conversion of hash signature algorithm into ASN.1 OID.
  * 
- * @ingroup hashers
+ * @param alg                  hash algorithm
+ * @return                             ASN.1 OID if, or OID_UNKNOW
  */
 int hasher_signature_algorithm_to_oid(hash_algorithm_t alg);
 
-#endif /* HASHER_H_ */
+#endif /* HASHER_H_ @} */
diff --git a/src/libstrongswan/crypto/ietf_attr_list.c b/src/libstrongswan/crypto/ietf_attr_list.c
deleted file mode 100644 (file)
index 1ecadf6..0000000
+++ /dev/null
@@ -1,405 +0,0 @@
-/**
- * @file ietf_attr.c
- * 
- * @brief Implementation of ietfAttr_t.
- * 
- */
-
-/* 
- * Copyright (C) 2007 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 <string.h>
-#include <stdio.h>
-
-#include <debug.h>
-#include <asn1/asn1.h>
-#include <utils/lexparser.h>
-
-#include "ietf_attr_list.h"
-
-/**
- * Private definition of ietfAttribute kinds
- */
-typedef enum {
-       IETF_ATTRIBUTE_OCTETS = 0,
-       IETF_ATTRIBUTE_OID =    1,
-       IETF_ATTRIBUTE_STRING = 2
-} ietfAttribute_t;
-
-typedef struct ietfAttr_t ietfAttr_t;
-
-/**
- * Private definition of an ietfAttribute
- */
-struct ietfAttr_t {
-       /**
-        * IETF attribute kind
-        */
-       ietfAttribute_t kind;
-
-       /**
-        * IETF attribute valuse
-        */
-       chunk_t value;
-
-       /**
-        * Compares two ietfAttributes
-        *      
-        * return -1 if this is earlier in the alphabet than other
-        * return  0 if this equals other
-        * return +1 if this is later in the alphabet than other
-        *
-        * @param this          calling object
-        * @param other         other object
-        */
-       int (*compare) (const ietfAttr_t *this ,const ietfAttr_t *other);
-
-       /**
-        * Destroys the ietfAttr_t object.
-        * 
-        * @param this                  ietfAttr_t to destroy
-        */
-       void (*destroy) (ietfAttr_t *this);
-};
-
-/**
- * Implements ietfAttr_t.compare.
- */
-static int ietfAttr_compare(const ietfAttr_t *this ,const ietfAttr_t *other)
-{
-       int cmp_len, len, cmp_value;
-
-       /* OID attributes are appended after STRING and OCTETS attributes */
-       if (this->kind != IETF_ATTRIBUTE_OID && other->kind == IETF_ATTRIBUTE_OID)
-       {
-               return -1;
-       }
-       if (this->kind == IETF_ATTRIBUTE_OID && other->kind != IETF_ATTRIBUTE_OID)
-       {
-               return 1;
-       }
-       
-    cmp_len = this->value.len - other->value.len;
-    len = (cmp_len < 0)? this->value.len : other->value.len;
-    cmp_value = memcmp(this->value.ptr, other->value.ptr, len);
-
-    return (cmp_value == 0)? cmp_len : cmp_value;
-}
-
-/**
- * Implements ietfAttr_t.destroy.
- */
-static void ietfAttr_destroy(ietfAttr_t *this)
-{
-       free(this->value.ptr);
-       free(this);
-}
-
-/**
- * Creates an ietfAttr_t object.
- */
-static ietfAttr_t *ietfAttr_create(ietfAttribute_t kind, chunk_t value)
-{
-       ietfAttr_t *this = malloc_thing(ietfAttr_t);
-
-       /* initialize */
-       this->kind = kind;
-       this->value = chunk_clone(value);
-
-       /* function */
-       this->compare = ietfAttr_compare;
-       this->destroy = ietfAttr_destroy;
-
-       return this;
-}
-
-/**
- * Adds an ietfAttr_t object to a sorted linked list
- */
-static void ietfAttr_add(linked_list_t *list, ietfAttr_t *attr)
-{
-       iterator_t *iterator = list->create_iterator(list, TRUE);
-       ietfAttr_t *current_attr;
-       bool found = FALSE;
-
-       while (iterator->iterate(iterator, (void **)&current_attr))
-       {
-               int cmp = attr->compare(attr, current_attr);
-
-               if (cmp > 0)
-               {
-                        continue;
-               }
-               if (cmp == 0)
-               {
-                       attr->destroy(attr);
-               }
-               else
-               {
-                       iterator->insert_before(iterator, attr);
-               }
-               found = TRUE;
-               break;
-       }
-       iterator->destroy(iterator);
-       if (!found)
-       {
-               list->insert_last(list, attr);
-       }
-}
-
-/*
- * Described in header.
- */
-bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b)
-{
-        bool result = TRUE;
-
-       /* lists must have the same number of attributes */
-       if (list_a->get_count(list_a) != list_b->get_count(list_b))
-       {
-               return FALSE;
-       }
-       /* empty lists - no attributes */
-       if (list_a->get_count(list_a) == 0)
-       {
-               return TRUE;
-       }
-
-       /* compare two alphabetically-sorted lists */
-       {
-               iterator_t *iterator_a = list_a->create_iterator(list_a, TRUE);
-               iterator_t *iterator_b = list_b->create_iterator(list_b, TRUE);
-               ietfAttr_t *attr_a, *attr_b;
-
-               while (iterator_a->iterate(iterator_a, (void **)&attr_a) &&
-                          iterator_b->iterate(iterator_b, (void **)&attr_b))
-               {
-                       if (attr_a->compare(attr_a, attr_b) != 0)
-                       {
-                               /* we have a mismatch */
-                               result = FALSE;
-                               break;
-                       }
-               }
-               iterator_a->destroy(iterator_a);
-               iterator_b->destroy(iterator_b);
-       }
-       return result;
-}
-
-/*
- * Described in header.
- */
-void ietfAttr_list_list(linked_list_t *list, FILE *out)
-{
-       iterator_t *iterator = list->create_iterator(list, TRUE);
-       ietfAttr_t *attr;
-       bool first = TRUE;
-
-       while (iterator->iterate(iterator, (void **)&attr))
-       {
-               if (first)
-               {
-                       first = FALSE;
-               }
-               else
-               {
-                       fprintf(out, ", ");
-               }
-
-               switch (attr->kind)
-               {
-                       case IETF_ATTRIBUTE_OCTETS:
-                       case IETF_ATTRIBUTE_STRING:
-                               fprintf(out, "%.*s", (int)attr->value.len, attr->value.ptr);
-                               break;
-                       case IETF_ATTRIBUTE_OID:
-                               {
-                                       int oid = known_oid(attr->value);
-
-                                       if (oid == OID_UNKNOWN)
-                                       {
-                                               fprintf(out, "0x#B", &attr->value);
-                                       }
-                                       else
-                                       {
-                                               fprintf(out, "%s", oid_names[oid]);
-                                       }
-                               }
-                       break;
-                       default:
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-}
-
-/*
- * Described in header.
- */
-void ietfAttr_list_create_from_string(char *msg, linked_list_t *list)
-{
-       chunk_t line = { msg, strlen(msg) };
-
-       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)
-               {
-                       ietfAttr_t *attr = ietfAttr_create(IETF_ATTRIBUTE_STRING, group);
-               
-                       ietfAttr_add(list, attr);
-               }
-       }
-}
-
-/**
- * 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 */
-};
-
-#define IETF_ATTR_OCTETS        4
-#define IETF_ATTR_OID           6
-#define IETF_ATTR_STRING        8
-#define IETF_ATTR_ROOF         11
-
-/*
- * Described in header.
- */
-void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-
-       asn1_init(&ctx, chunk, level0, FALSE, FALSE);
-
-       while (objectID < IETF_ATTR_ROOF)
-       {
-               if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx))
-               {
-                       return;
-               }
-
-               switch (objectID)
-               {
-                       case IETF_ATTR_OCTETS:
-                       case IETF_ATTR_OID:
-                       case IETF_ATTR_STRING:
-                               {
-                                       ietfAttribute_t kind = (objectID - IETF_ATTR_OCTETS) / 2;
-                                       ietfAttr_t *attr   = ietfAttr_create(kind, object);
-                                       ietfAttr_add(list, attr);
-                               }
-                               break;
-                       default:
-                               break;
-               }
-               objectID++;
-       }
-}
-
-/*
- * Described in header.
- */
-chunk_t ietfAttr_list_encode(linked_list_t *list)
-{
-       chunk_t ietfAttributes;
-       size_t size = 0;
-       u_char *pos;
-       iterator_t *iterator = list->create_iterator(list, TRUE);
-       ietfAttr_t *attr;
-
-       /* precalculate the total size of all values */
-       while (iterator->iterate(iterator, (void **)&attr))
-       {
-               size_t len = attr->value.len;
-
-               size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
-       }
-       iterator->destroy(iterator);
-
-       pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size);
-
-       iterator = list->create_iterator(list, TRUE);
-       while (iterator->iterate(iterator, (void **)&attr))
-       {
-               chunk_t ietfAttribute;
-               asn1_t type = ASN1_NULL;
-
-               switch (attr->kind)
-               {
-                       case IETF_ATTRIBUTE_OCTETS:
-                               type = ASN1_OCTET_STRING;
-                               break;
-                       case IETF_ATTRIBUTE_STRING:
-                               type = ASN1_UTF8STRING;
-                               break;
-                       case IETF_ATTRIBUTE_OID:
-                               type = ASN1_OID;
-                               break;
-               }
-               ietfAttribute = asn1_simple_object(type, attr->value);
-
-               /* copy ietfAttribute into ietfAttributes chunk */
-               memcpy(pos, ietfAttribute.ptr, ietfAttribute.len); 
-               pos += ietfAttribute.len;
-               free(ietfAttribute.ptr);
-       }
-       iterator->destroy(iterator);
-
-       return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
-}
-
-/*
- * Described in header.
- */
-void ietfAttr_list_destroy(linked_list_t *list)
-{
-       list->destroy_offset(list, offsetof(ietfAttr_t, destroy));
-}
diff --git a/src/libstrongswan/crypto/ietf_attr_list.h b/src/libstrongswan/crypto/ietf_attr_list.h
deleted file mode 100644 (file)
index 75407bb..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file ietf_attr_list.h
- * 
- * @brief Handling of ietfAttr_t linked lists
- * 
- */
-
-/*
- * Copyright (C) 2007 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.
- */
-
-#ifndef IETF_ATTR_LIST_H_
-#define IETF_ATTR_LIST_H_
-
-#include <library.h>
-#include <utils/linked_list.h>
-
-
-/**
- * @brief Compare two linked lists of ietfAttr_t objects for equality
- *
- * @param list_a       first alphabetically-sorted list
- * @param list_b       second alphabetically-sorted list
- * @return                     TRUE if equal   
- *
- * @ingroup crypto
- */
-bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b);
-
-/**
- * @brief Lists a linked list of ietfAttr_t objects
- *
- * @param list         alphabetically-sorted linked list of attributes
-   @param out          output file     
- *
- * @ingroup crypto
- */
-void ietfAttr_list_list(linked_list_t *list, FILE *out);
-
-/**
- * @brief Create a linked list of ietfAttr_t objects from a string
- *
- * @param msg          string with comma-separated group names
- * @param list         alphabetically-sorted linked list of attributes
- *
- * @ingroup crypto
- */
-void ietfAttr_list_create_from_string(char *msg, linked_list_t *list);
-
-/**
- * @brief Create a linked list of ietfAttr_t objects from an ASN.1-coded chunk
- *
- * @param chunk                chunk containing ASN.1-coded attributes
- * @param list         alphabetically-sorted linked list of attributes
- * @param level0       parsing level
- */
-void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0);
-
-/**
- * @brief Encode a linked list of ietfAttr_t objects into an ASN.1-coded chunk
- *
- * @param list         alphabetically-sorted linked list of attributes
- * @return                     chunk containing ASN.1-coded attributes
- */
-chunk_t ietfAttr_list_encode(linked_list_t *list);
-
-/**
- * @brief Destroys a linked list of ietfAttr_t objects
- *
- * @param list         list to be destroyed
- *
- * @ingroup crypto
- */
-void ietfAttr_list_destroy(linked_list_t *list);
-
-#endif /* IETF_ATTR_LIST_H_ */
-
diff --git a/src/libstrongswan/crypto/ocsp.c b/src/libstrongswan/crypto/ocsp.c
deleted file mode 100644 (file)
index 4bbec31..0000000
+++ /dev/null
@@ -1,934 +0,0 @@
-/**
- * @file ocsp.c
- * 
- * @brief Implementation of ocsp_t.
- * 
- */
-
-/* Support of the Online Certificate Status Protocol (OCSP)
- *
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2007 Andreas Steffen
- *
- * Hochschule für Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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$
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <utils/identification.h>
-#include <utils/randomizer.h>
-#include <utils/fetcher.h>
-#include <debug.h>
-
-#include "hashers/hasher.h"
-#include "rsa/rsa_public_key.h"
-#include "certinfo.h"
-#include "x509.h"
-#include "ocsp.h"
-
-#define NONCE_LENGTH           16
-
-typedef struct private_ocsp_t private_ocsp_t;
-
-/**
- * Private data of a ocsp_t object.
- */
-struct private_ocsp_t {
-       /**
-        * Public interface for this ocsp object.
-        */
-       ocsp_t public;
-
-       /**
-        * CA certificate.
-        */
-       x509_t *cacert;
-
-       /**
-        * Requestor certificate
-        */
-       x509_t *requestor_cert;
-
-       /**
-        * Linked list of ocsp uris
-        */
-       linked_list_t *uris;
-
-       /**
-        * Linked list of certinfos to be requested
-        */
-       linked_list_t *certinfos;
-
-       /**
-        * Nonce required for ocsp request and response
-        */
-       chunk_t nonce;
-
-       /**
-        * SHA-1 hash over issuer distinguished name
-        */
-       chunk_t authNameID;
-
-       /**
-        * SHA-1 hash over issuer public key
-        */
-       chunk_t authKeyID;
-};
-
-ENUM(response_status_names, STATUS_SUCCESSFUL, STATUS_UNAUTHORIZED,
-       "successful",
-       "malformed request",
-       "internal error",
-       "try later",
-       "signature required",
-       "unauthorized"
-);
-
-/* response container */
-typedef struct response_t response_t;
-
-struct response_t {
-       chunk_t           chunk;
-       chunk_t           tbs;
-       identification_t *responder_id_name;
-       chunk_t           responder_id_key;
-       time_t            produced_at;
-       chunk_t           responses;
-       chunk_t           nonce;
-       int               algorithm;
-       chunk_t           signature;
-       x509_t           *responder_cert;
-
-       /**
-        * @brief Destroys the response_t object
-        * 
-        * @param this          response_t to destroy
-        */
-       void (*destroy) (response_t *this);
-};
-
-/**
- * Implements response_t.destroy.
- */
-static void response_destroy(response_t *this)
-{
-       DESTROY_IF(this->responder_id_name);
-       DESTROY_IF(this->responder_cert);
-       free(this->chunk.ptr);
-       free(this);
-}
-
-/**
- * Creates a response_t object
- */
-static response_t* response_create_from_chunk(chunk_t chunk)
-{
-       response_t *this = malloc_thing(response_t);
-
-       this->chunk             = chunk;
-       this->tbs               = chunk_empty;
-       this->responder_id_name = NULL;
-       this->responder_id_key  = chunk_empty;
-       this->produced_at       = UNDEFINED_TIME;
-       this->responses         = chunk_empty;
-       this->nonce             = chunk_empty;
-       this->algorithm         = OID_UNKNOWN;
-       this->signature         = chunk_empty;
-       this->responder_cert    = NULL;
-
-       this->destroy = (void (*) (response_t*))response_destroy;
-
-       return this;
-}
-
-/* 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
-};
-
-static u_char ASN1_response_oid_str[] = {
-       0x06, 0x09,
-                 0x2B, 0x06,
-                               0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
-};
-
-static u_char ASN1_response_content_str[] = {
-       0x04, 0x0D,
-                 0x30, 0x0B,
-                               0x06, 0x09,
-                               0x2B, 0x06,
-                               0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
-};
-
-static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
-static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
-static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
-
-/* asn.1 definitions for parsing */
-
-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 */
-};
-
-#define OCSP_RESPONSE_STATUS   1
-#define OCSP_RESPONSE_TYPE             4
-#define OCSP_RESPONSE                  5
-#define OCSP_RESPONSE_ROOF             7
-
-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_RAW  }, /* 24 */
-       { 2,     "end loop",                                    ASN1_EOC,                               ASN1_END  }, /* 25 */
-       { 1,   "end opt",                                               ASN1_EOC,                               ASN1_END  }  /* 26 */
-};
-
-#define BASIC_RESPONSE_TBS_DATA                 1
-#define BASIC_RESPONSE_VERSION          3
-#define BASIC_RESPONSE_ID_BY_NAME       5
-#define BASIC_RESPONSE_ID_BY_KEY        8
-#define BASIC_RESPONSE_PRODUCED_AT     10
-#define BASIC_RESPONSE_RESPONSES       11
-#define BASIC_RESPONSE_EXT_ID          15
-#define BASIC_RESPONSE_CRITICAL                16
-#define BASIC_RESPONSE_EXT_VALUE       17
-#define BASIC_RESPONSE_ALGORITHM       20
-#define BASIC_RESPONSE_SIGNATURE       21
-#define BASIC_RESPONSE_CERTIFICATE     24
-#define BASIC_RESPONSE_ROOF                    27
-
-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 */
-};
-
-#define RESPONSES_SINGLE_RESPONSE      1
-#define RESPONSES_ROOF                         3
-
-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 */
-};
-
-#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 requestorName (into TBSRequest)
- */
-static chunk_t build_requestor_name(private_ocsp_t *this)
-{
-       identification_t *requestor_name = this->requestor_cert->get_subject(this->requestor_cert);
-
-       return asn1_wrap(ASN1_CONTEXT_C_1, "m",
-                               asn1_simple_object(ASN1_CONTEXT_C_4,
-                                       requestor_name->get_encoding(requestor_name)));
-}
-
-/**
- * build request (into requestList)
- * no singleRequestExtensions used
- */
-static chunk_t build_request(private_ocsp_t *this, certinfo_t *certinfo)
-{
-       chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
-
-       chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm",
-               asn1_algorithmIdentifier(OID_SHA1),
-               asn1_simple_object(ASN1_OCTET_STRING, this->authNameID),
-               asn1_simple_object(ASN1_OCTET_STRING, this->authKeyID),
-               asn1_simple_object(ASN1_INTEGER, serialNumber));
-
-       return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
-}
-
-/**
- * build requestList (into TBSRequest)
- */
-static chunk_t build_request_list(private_ocsp_t *this)
-{
-       chunk_t requestList;
-       size_t datalen = 0;
-       linked_list_t *request_list = linked_list_create();
-
-       {
-               iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
-               certinfo_t *certinfo;
-
-               while (iterator->iterate(iterator, (void**)&certinfo))
-               {
-                       chunk_t *request = malloc_thing(chunk_t);
-
-                       *request = build_request(this, certinfo);
-                       request_list->insert_last(request_list, (void*)request);
-                       datalen += request->len;
-               }
-               iterator->destroy(iterator);
-       }
-       {
-               iterator_t *iterator = request_list->create_iterator(request_list, TRUE);
-               chunk_t *request;
-
-       u_char *pos = build_asn1_object(&requestList, ASN1_SEQUENCE, datalen);
-
-               while (iterator->iterate(iterator, (void**)&request))
-               {
-                       memcpy(pos, request->ptr, request->len); 
-                       pos += request->len;
-                       free(request->ptr);
-                       free(request);
-               }
-               iterator->destroy(iterator);
-               request_list->destroy(request_list);
-       }
-       return requestList;
-}
-
-/**
- * build nonce extension (into requestExtensions)
- */
-static chunk_t build_nonce_extension(private_ocsp_t *this)
-{
-       randomizer_t *randomizer = randomizer_create();
-
-    /* generate a random nonce */
-       randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LENGTH, &this->nonce);
-       randomizer->destroy(randomizer);
-
-    return asn1_wrap(ASN1_SEQUENCE, "cm",
-               ASN1_nonce_oid,
-               asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
-}
-
-/**
- * build requestExtensions (into TBSRequest)
- */
-static chunk_t build_request_ext(private_ocsp_t *this)
-{
-    return asn1_wrap(ASN1_CONTEXT_C_2, "m",
-               asn1_wrap(ASN1_SEQUENCE, "mm",
-                       build_nonce_extension(this),
-                   asn1_wrap(ASN1_SEQUENCE, "cc",
-                               ASN1_response_oid,
-                               ASN1_response_content
-                       )
-               )
-       );
-}
-
-/**
- * build TBSRequest (into OCSPRequest)
- */
-static chunk_t build_tbs_request(private_ocsp_t *this, bool has_requestor_cert)
-{
-       /* version is skipped since the default is ok */
-       return asn1_wrap(ASN1_SEQUENCE, "mmm",
-               (has_requestor_cert)? build_requestor_name(this): chunk_empty,
-               build_request_list(this),
-               build_request_ext(this));
-}
-
-/**
- * build signature into ocsp request
- * gets built only if a request cert with a corresponding private key is found
- */
-static chunk_t build_signature(private_ocsp_t *this, chunk_t tbsRequest)
-{
-       /* TODO */
-       return chunk_empty;
-}
-
-/**
- * assembles an ocsp request and sets the nonce field in private_ocsp_t to the sent nonce
- */
-static chunk_t ocsp_build_request(private_ocsp_t *this)
-{
-       bool has_requestor_cert;
-       chunk_t keyid = this->cacert->get_keyid(this->cacert);
-       chunk_t tbsRequest, signature;
-
-       DBG2("assembling ocsp request");
-       DBG2("issuer: '%D'", this->cacert->get_subject(this->cacert));
-       DBG2("keyid:   %#B", &keyid);
-
-       /* looks for requestor cert and matching private key */
-       has_requestor_cert = FALSE;
-
-    /* TODO has_requestor_cert = get_ocsp_requestor_cert(location); */
-
-       /* build content */
-       tbsRequest = build_tbs_request(this, has_requestor_cert);
-
-       /* sign tbsReuqest */
-       signature = (has_requestor_cert)? build_signature(this, tbsRequest): chunk_empty;
-
-       return asn1_wrap(ASN1_SEQUENCE, "mm",
-               tbsRequest,
-               signature);
-
-       return signature;
-}
-
-/**
- * parse a basic OCSP response
- */
-static bool ocsp_parse_basic_response(chunk_t blob, int level0, response_t *res)
-{
-       u_int level, version;
-       asn1_ctx_t ctx;
-       bool critical;
-       chunk_t object;
-       int objectID = 0;
-       int extn_oid = OID_UNKNOWN;
-
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
-       while (objectID < BASIC_RESPONSE_ROOF)
-       {
-               if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
-               {
-                       return FALSE;
-               }
-
-               switch (objectID)
-               {
-                       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)
-                               {
-                                       DBG1("wrong ocsp basic response version (version= %i)",  version);
-                                       return FALSE;
-                               }
-                               break;
-                       case BASIC_RESPONSE_ID_BY_NAME:
-                               res->responder_id_name = identification_create_from_encoding(ID_DER_ASN1_DN, object);
-                               DBG2("  '%D'", res->responder_id_name);
-                               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;
-                               DBG2("  %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 = chunk_clone(object);
-
-                                       res->responder_cert = x509_create_from_chunk(blob, level+1);
-                               }
-                               break;
-               }
-               objectID++;
-       }
-       return TRUE;
-}
-
-/**
- * parse an ocsp response and return the result as a response_t struct
- */
-static response_status ocsp_parse_response(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, res->chunk, 0, FALSE, FALSE);
-
-       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;
-                               DBG2("  '%N'", response_status_names, rStatus);
-                               switch (rStatus)
-                       {
-                               case STATUS_SUCCESSFUL:
-                                               break;
-                                       case STATUS_MALFORMEDREQUEST:
-                                       case STATUS_INTERNALERROR:
-                                       case STATUS_TRYLATER:
-                                       case STATUS_SIGREQUIRED:
-                                       case STATUS_UNAUTHORIZED:
-                                               DBG1("unsuccessful ocsp response: server said '%N'",
-                                                        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 (!ocsp_parse_basic_response(object, level+1, res))
-                                                       {
-                                                               return STATUS_INTERNALERROR;
-                                                       }
-                                                       break;
-                                               default:
-                                                       DBG1("ocsp response is not of type BASIC");
-                                                       DBG1("ocsp response OID: %#B", &object);
-                                                       return STATUS_INTERNALERROR;
-                                       }
-                               }
-                               break;
-               }
-               objectID++;
-       }
-       return rStatus;
-}
-
-/**
- * Check if the OCSP response has a valid signature
- */
-static bool ocsp_valid_response(response_t *res, x509_t *ocsp_cert)
-{
-       rsa_public_key_t *public_key;
-       time_t until = UNDEFINED_TIME;
-       err_t ugh;
-       hash_algorithm_t algorithm = hasher_algorithm_from_oid(res->algorithm);
-
-       if (algorithm == HASH_UNKNOWN)
-       {
-               DBG1("unknown signature algorithm");
-               return FALSE;
-       }
-
-       DBG2("verifying ocsp response signature:");
-       DBG2("signer:  '%D'", ocsp_cert->get_subject(ocsp_cert));
-       DBG2("issuer:  '%D'", ocsp_cert->get_issuer(ocsp_cert));
-
-       ugh = ocsp_cert->is_valid(ocsp_cert, &until);
-       if (ugh != NULL)
-       {
-               DBG1("ocsp signer certificate %s", ugh);
-               return FALSE;
-       }
-       public_key = ocsp_cert->get_public_key(ocsp_cert);
-       
-       return public_key->verify_emsa_pkcs1_signature(public_key, algorithm, res->tbs, res->signature) == SUCCESS;
-}
-
-/**
- * parse a single OCSP response
- */
-static bool ocsp_parse_single_response(private_ocsp_t *this, chunk_t blob, int level0)
-{
-       u_int level, extn_oid;
-       asn1_ctx_t ctx;
-       bool critical;
-       chunk_t object;
-       int objectID = 0;
-
-       certinfo_t *certinfo = NULL;
-
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
-       while (objectID < SINGLE_RESPONSE_ROOF)
-       {
-               if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
-               {
-                       return FALSE;
-               }
-
-               switch (objectID)
-               {
-                       case SINGLE_RESPONSE_ALGORITHM:
-                               if (parse_algorithmIdentifier(object, level+1, NULL) != OID_SHA1)
-                               {
-                                       DBG1("only sha-1 hash supported in ocsp single response");
-                                       return FALSE;
-                               }
-                               break;
-                       case SINGLE_RESPONSE_ISSUER_NAME_HASH:
-                       if (!chunk_equals(object, this->authNameID))
-                               {
-                                       DBG1("ocsp single response has wrong issuer name hash");
-                                       return FALSE;
-                               }
-                               break;
-                       case SINGLE_RESPONSE_ISSUER_KEY_HASH:
-                       if (!chunk_equals(object, this->authKeyID))
-                               {
-                                       DBG1("ocsp single response has wrong issuer key hash");
-                                       return FALSE;
-                               }
-                               break;
-                       case SINGLE_RESPONSE_SERIAL_NUMBER:
-                               {
-                                       iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
-                                       certinfo_t *current_certinfo;
-
-                                       while (iterator->iterate(iterator, (void**)&current_certinfo))
-                                       {
-                                               if (chunk_equals(object, current_certinfo->get_serialNumber(current_certinfo)))
-                                               {
-                                                       certinfo = current_certinfo;
-                                               }
-                                       }
-                                       iterator->destroy(iterator);
-                                       if (certinfo == NULL)
-                                       {
-                                               DBG1("unrequested serial number in ocsp single response");
-                                               return FALSE;
-                                       }
-                               }
-                               break;
-                       case SINGLE_RESPONSE_CERT_STATUS_GOOD:
-                               certinfo->set_status(certinfo, CERT_GOOD);
-                               break;
-                       case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
-                               certinfo->set_status(certinfo, CERT_REVOKED);
-                               break;
-                       case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
-                               certinfo->set_revocationTime(certinfo,
-                                                                asn1totime(&object, ASN1_GENERALIZEDTIME));
-                               break;
-                       case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
-                               certinfo->set_revocationReason(certinfo,
-                                                               (object.len == 1) ? *object.ptr : REASON_UNSPECIFIED);
-                       break;
-                       case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
-                               certinfo->set_status(certinfo, CERT_UNKNOWN);
-                               break;
-                       case SINGLE_RESPONSE_THIS_UPDATE:
-                               certinfo->set_thisUpdate(certinfo,
-                                                               asn1totime(&object, ASN1_GENERALIZEDTIME));
-                               break;
-                       case SINGLE_RESPONSE_NEXT_UPDATE:
-                               certinfo->set_nextUpdate(certinfo,
-                                                               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;
-                               DBG2("  %s", critical ? "TRUE" : "FALSE");
-                       case SINGLE_RESPONSE_EXT_VALUE:
-                               break;
-               }
-               objectID++;
-       }
-       return TRUE;
-}
-
-/**
- *  verify and process ocsp response and update the ocsp cache
- */
-static void ocsp_process_response(private_ocsp_t *this, response_t *res, credential_store_t *credentials)
-{
-       x509_t *ocsp_cert = NULL;
-
-       /* parse the ocsp response without looking at the single responses yet */
-       response_status status = ocsp_parse_response(res);
-
-       if (status != STATUS_SUCCESSFUL)
-       {
-               DBG1("error in ocsp response");
-               return;
-       }
-
-       /* check if there was a nonce in the request */
-       if (this->nonce.ptr != NULL && res->nonce.ptr == NULL)
-       {
-               DBG1("ocsp response contains no nonce, replay attack possible");
-       }
-
-       /* check if the nonces are identical */
-       if (res->nonce.ptr != NULL && !chunk_equals(res->nonce, this->nonce))
-    {
-               DBG1("invalid nonce in ocsp response");
-               return;
-       }
-
-       /* check if we received a trusted responder certificate */
-       if (res->responder_cert)
-       {
-               if (res->responder_cert->is_ocsp_signer(res->responder_cert))
-               {
-                       DBG2("received certificate is ocsp signer");
-                       if (credentials->is_trusted(credentials, "OCSP signing", res->responder_cert))
-                       {
-                               DBG1("received ocsp signer certificate is trusted");
-                               ocsp_cert = credentials->add_auth_certificate(credentials,
-                                                                       res->responder_cert, AUTH_OCSP);
-                               res->responder_cert = NULL;
-                       }
-                       else
-                       {
-                               DBG1("received ocsp signer certificate is not trusted - rejected");
-                       }
-               }
-               else
-               {
-                       DBG1("received certificate is no ocsp signer - rejected");
-               }
-       }
-
-       /* if we didn't receive a trusted responder cert, search the credential store */
-       if (ocsp_cert == NULL)
-       {
-               ocsp_cert = credentials->get_auth_certificate(credentials,
-                                                       AUTH_OCSP|AUTH_CA, res->responder_id_name);
-               if (ocsp_cert == NULL)
-               {
-                       DBG1("no ocsp signer certificate found");
-                       return;
-               }
-       }
-
-       /* check the response signature */
-       if (!ocsp_valid_response(res, ocsp_cert))
-       {
-               DBG1("ocsp response signature is invalid");
-               return;
-       }
-       DBG2("ocsp response signature is valid");
-
-    /* now parse the single responses one at a time */
-    {
-               u_int level;
-               asn1_ctx_t ctx;
-               chunk_t object;
-               int objectID = 0;
-
-               asn1_init(&ctx, res->responses, 0, FALSE, FALSE);
-
-               while (objectID < RESPONSES_ROOF)
-               {
-                       if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
-                       {
-                               return;
-                       }
-                       if (objectID == RESPONSES_SINGLE_RESPONSE)
-                       {
-                               ocsp_parse_single_response(this, object, level+1);
-                       }
-                       objectID++;
-               }
-       }
-}
-
-/**
- * Implements ocsp_t.fetch.
- */
-static void fetch(private_ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials)
-{
-       chunk_t request;
-       response_t *response = NULL;
-
-       if (this->uris->get_count(this->uris) == 0)
-       {
-               return;
-       }
-       this->certinfos->insert_last(this->certinfos, (void*)certinfo);
-
-       request = ocsp_build_request(this);
-       DBG3("ocsp request: %B", &request);
-       {
-               iterator_t *iterator = this->uris->create_iterator(this->uris, TRUE);
-               identification_t *uri;
-               
-               while (iterator->iterate(iterator, (void**)&uri))
-               {
-                       fetcher_t *fetcher;
-                       char uri_string[BUF_LEN];
-                       chunk_t uri_chunk = uri->get_encoding(uri);
-                       chunk_t response_chunk;
-
-                       snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
-                       fetcher = fetcher_create(uri_string);
-                       
-                       response_chunk = fetcher->post(fetcher, "application/ocsp-request", request);
-                       fetcher->destroy(fetcher);
-                       if (response_chunk.ptr != NULL)
-                       {
-                               response = response_create_from_chunk(response_chunk);
-                               break;
-                       }
-               }
-               iterator->destroy(iterator);
-       }
-       free(request.ptr);
-
-       if (response == NULL)
-       {
-               return;
-       }
-       DBG3("ocsp response: %B", &response->chunk);
-       ocsp_process_response(this, response, credentials);
-       response->destroy(response);
-}
-
-/**
- * Implements ocsp_t.destroy.
- */
-static void destroy(private_ocsp_t *this)
-{
-       this->certinfos->destroy(this->certinfos);
-       free(this->authNameID.ptr);
-       free(this->nonce.ptr);
-       free(this);
-}
-
-/*
- * Described in header.
- */
-ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris)
-{
-       private_ocsp_t *this = malloc_thing(private_ocsp_t);
-
-       /* initialize */
-       this->cacert = cacert;
-       this->uris = uris;
-       this->certinfos = linked_list_create();
-       this->nonce = chunk_empty;
-       this->authKeyID = cacert->get_subjectKeyID(cacert);
-       {
-               hasher_t *hasher = hasher_create(HASH_SHA1);
-               identification_t *issuer = cacert->get_subject(cacert);
-
-               hasher->allocate_hash(hasher, issuer->get_encoding(issuer),
-                                                                         &this->authNameID);
-               hasher->destroy(hasher);
-       }
-
-       /* public functions */
-       this->public.fetch = (void (*) (ocsp_t*,certinfo_t*,credential_store_t*))fetch;
-       this->public.destroy = (void (*) (ocsp_t*))destroy;
-
-       return &this->public;
-}
index e468bb8beefdfb60a77bfeb26008a1eafdf92b3c..b358d409fc31f331278a6761fbe3147441639157 100644 (file)
@@ -1,12 +1,4 @@
-/**
- * @file ocsp.h
- * 
- * @brief Interface of ocsp_t
- * 
- */
-
-/* Support of the Online Certificate Status Protocol (OCSP) Support
- *
+/*
  * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
  * Copyright (C) 2007 Andreas Steffen
  *
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
+ */
+/**
+ * @defgroup ocsp ocsp
+ * @{ @ingroup crypto
  */
 
 #ifndef OCSP_H_
@@ -51,39 +48,32 @@ typedef enum {
 } response_status;
 
 /**
- * @brief Online Certficate Status Protocol (OCSP)
- *
- * @ingroup transforms
+ * Online Certficate Status Protocol (OCSP)
  */
 struct ocsp_t {
 
        /**
-        * @brief Fetches the actual certificate status via OCSP
+        * Fetches the actual certificate status via OCSP
         * 
-        * @param uris                          linked list of ocsp uris
         * @param certinfo                      certificate status info to be updated
         * @param credentials           credential store needed for trust path verification
         */
        void (*fetch) (ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials);
 
        /**
-        * @brief Destroys the ocsp_t object.
-        * 
-        * @param this                  ocsp object to destroy
+        * Destroys the ocsp_t object.
         */
        void (*destroy) (ocsp_t *this);
 
 };
 
 /**
- * @brief Create an ocsp_t object.
+ * Create an ocsp_t object.
  * 
  * @param cacert       ca certificate
  * @param uris         linked list of ocsp uris
  * @return                     created ocsp_t object
- * 
- * @ingroup transforms
  */
 ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris);
 
-#endif /* OCSP_H_ */
+#endif /* OCSP_H_ @} */
index 252fc19b2265b68f95ffa8671180c0827f59ac96..662e8dd0df7582e855de2ca6a2eca40ef0631776 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file pkcs7.c
- *
- * @brief Implementation of pkcs7_t.
- *
- */
-
 /*
  * Copyright (C) 2005 Jan Hutter, Martin Willi
  * Copyright (C) 2002-2008 Andreas Steffen
@@ -21,7 +14,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
  */
 
 #include <stdlib.h>
@@ -459,10 +452,18 @@ static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert)
                        }
                        else
                        {
-                               hasher_t *hasher = hasher_create(algorithm);
+                               hasher_t *hasher;
                                chunk_t hash;
                                bool valid;
 
+                               hasher = lib->crypto->create_hasher(lib->crypto, algorithm)
+                               if (hasher == NULL)
+                               {
+                                       DBG1("hash algorithm %N not supported",
+                                                hash_algorithm_names, algorithm);
+                                       free(messageDigest.ptr);
+                                       return FALSE;
+                               }
                                hasher->allocate_hash(hasher, this->data, &hash);
                                hasher->destroy(hasher);
                                DBG3("hash: %B", &hash);
@@ -873,15 +874,24 @@ bool build_signedData(private_pkcs7_t *this, rsa_private_key_t *private_key,
 
        if (this->attributes != NULL)
        {
-               if (this->data.ptr != NULL)
+               if(this->data.ptr != NULL)
                {
+                       hasher_t *hasher;
+               
+                       hasher = lib->crypto->create_hasher(lib->crypto, alg);
+                       if (hasher == NULL)
+                       {
+                               DBG1("  hash algorithm %N not support",
+                                        hash_algorithm_names, alg);
+                               return FALSE;
+                       }
+               
                        /* take the current time as signingTime */
                        time_t now = time(NULL);
                        chunk_t signingTime = timetoasn1(&now, ASN1_UTCTIME);
 
                        chunk_t messageDigest, attributes;
-                       hasher_t *hasher = hasher_create(alg);
-               
+       
                        hasher->allocate_hash(hasher, this->data, &messageDigest);
                        hasher->destroy(hasher);
                        this->attributes->set_attribute(this->attributes,
index 1872673e639bafaec493d79167d1d0d422b96eb0..77d3ecdbd83a48d189abf5fed9e370b0ae70030c 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file pkcs7.h
- * 
- * @brief Interface of pkcs7_t.
- * 
- */
-
 /*
  * Copyright (C) 2005 Jan Hutter, Martin Willi
  * Copyright (C) 2002-2008 Andreas Steffen
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
+ */
+/**
+ * @defgroup pkcs7 pkcs7
+ * @{ @ingroup crypto
  */
 
-#ifndef _PKCS7_H
-#define _PKCS7_H
+#ifndef _PKCS7_H_
+#define _PKCS7_H_
 
 typedef struct pkcs7_t pkcs7_t;
 
@@ -37,60 +35,48 @@ typedef struct pkcs7_t pkcs7_t;
 #include <utils/iterator.h>
 
 /**
- * @brief PKCS#7 contentInfo object.
- * 
- * @b Constructors:
- *  -pkcs7_create_from_chunk()
- *  -pkcs7_create_from_data()
- *
- * @ingroup crypto
+ * PKCS#7 contentInfo object.
  */
 struct pkcs7_t {
        /**
-        * @brief Check if the PKCS#7 contentType is data
+        * Check if the PKCS#7 contentType is data
         * 
-        * @param this                  calling object
         * @return                              TRUE if the contentType is data
         */
        bool (*is_data) (pkcs7_t *this);
 
        /**
-        * @brief Check if the PKCS#7 contentType is signedData
+        * Check if the PKCS#7 contentType is signedData
         * 
-        * @param this                  calling object
         * @return                              TRUE if the contentType is signedData
         */
        bool (*is_signedData) (pkcs7_t *this);
 
        /**
-        * @brief Check if the PKCS#7 contentType is envelopedData
+        * Check if the PKCS#7 contentType is envelopedData
         * 
-        * @param this                  calling object
         * @return                              TRUE if the contentType is envelopedData
         */
        bool (*is_envelopedData) (pkcs7_t *this);
 
        /**
-        * @brief Parse a PKCS#7 data content.
+        * Parse a PKCS#7 data content.
         * 
-        * @param this                  calling object
         * @return                              TRUE if parsing was successful
         */
        bool (*parse_data) (pkcs7_t *this);
 
        /**
-        * @brief Parse a PKCS#7 signedData content.
+        * Parse a PKCS#7 signedData content.
         * 
-        * @param this                  calling object
         * @param cacert                cacert used to verify the signature
         * @return                              TRUE if parsing was successful
         */
        bool (*parse_signedData) (pkcs7_t *this, x509_t *cacert);
 
        /**
-        * @brief Parse a PKCS#7 envelopedData content.
+        * Parse a PKCS#7 envelopedData content.
         * 
-        * @param this                  calling object
         * @param serialNumber  serialNumber of the request
         * @param key                   RSA private key used to decrypt the symmetric key
         * @return                              TRUE if parsing was successful
@@ -98,112 +84,97 @@ struct pkcs7_t {
        bool (*parse_envelopedData) (pkcs7_t *this, chunk_t serialNumber, rsa_private_key_t *key);
 
        /**
-        * @brief Returns the parsed data object
+        * Returns the parsed data object
         *
-        * @param this                  calling object
         * @return                              chunk containing the data object
         */
        chunk_t (*get_data) (pkcs7_t *this);
 
        /**
-        * @brief Returns the a DER-encoded contentInfo object
+        * Returns the a DER-encoded contentInfo object
         *
-        * @param this                  calling object
         * @return                              chunk containing the contentInfo object
         */
        chunk_t (*get_contentInfo) (pkcs7_t *this);
 
        /**
-        * @brief Create an iterator for the certificates.
+        * Create an iterator for the certificates.
         * 
-        * @param this                  calling object
         * @return                              iterator for the certificates
         */
        iterator_t *(*create_certificate_iterator) (pkcs7_t *this);
 
        /**
-        * @brief Add a certificate.
+        * Add a certificate.
         * 
-        * @param this                  calling object
         * @param cert                  certificate to be included
         */
        void (*set_certificate) (pkcs7_t *this, x509_t *cert);
 
        /**
-        * @brief Add authenticated attributes.
+        * Add authenticated attributes.
         * 
-        * @param this                  calling object
         * @param attributes    attributes to be included
         */
        void (*set_attributes) (pkcs7_t *this, pkcs9_t *attributes);
 
        /**
-        * @brief Build a data object
+        * Build a data object
         *
-        * @param this                  PKCS#7 data to be built
         * @return                              TRUE if build was successful
         */
        bool (*build_data) (pkcs7_t *this);
 
        /**
-        * @brief Build an envelopedData object
+        * Build an envelopedData object
         *
-        * @param this                  PKCS#7 data object to envelop
         * @param cert                  receivers's certificate
         * @param alg                   encryption algorithm
         * @return                              TRUE if build was successful
         */
-       bool (*build_envelopedData) (pkcs7_t *this, x509_t *cert, encryption_algorithm_t alg);
+       bool (*build_envelopedData) (pkcs7_t *this, x509_t *cert,
+                                                                encryption_algorithm_t alg);
 
        /**
-        * @brief Build an signedData object
+        * Build an signedData object
         *
-        * @param this                  PKCS#7 data object to sign
         * @param key                   signer's RSA private key
         * @param alg                   digest algorithm used for signature
         * @return                              TRUE if build was successful
         */
-       bool (*build_signedData) (pkcs7_t *this, rsa_private_key_t *key, hash_algorithm_t alg);
+       bool (*build_signedData) (pkcs7_t *this, rsa_private_key_t *key,
+                                                         hash_algorithm_t alg);
 
        /**
-        * @brief Destroys the contentInfo object.
-        *
-        * @param this                  PKCS#7 contentInfo object to destroy
+        * Destroys the contentInfo object.
         */
        void (*destroy) (pkcs7_t *this);
 };
 
 /**
- * @brief Read a PKCS#7 contentInfo object from a DER encoded chunk.
+ * Read a PKCS#7 contentInfo object from a DER encoded chunk.
  * 
  * @param chunk                chunk containing DER encoded data
  * @param level                ASN.1 parsing start level
  * @return                     created pkcs7_contentInfo object, or NULL if invalid.
- * 
- * @ingroup crypto
  */
 pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level);
 
 /**
- * @brief Create a PKCS#7 contentInfo object
+ * Create a PKCS#7 contentInfo object
  * 
  * @param chunk                        chunk containing data
  * @return                             created pkcs7_contentInfo object.
- * 
- * @ingroup crypto
  */
 pkcs7_t *pkcs7_create_from_data(chunk_t data);
 
 /**
- * @brief Read a X.509 certificate from a DER encoded file.
+ * Read a X.509 certificate from a DER encoded file.
  * 
  * @param filename     file containing DER encoded data
  * @param label                label describing kind of PKCS#7 file
  * @return                     created pkcs7_t object, or NULL if invalid.
- * 
- * @ingroup crypto
  */
 pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label);
 
-
-#endif /* _PKCS7_H */
+#endif /* _PKCS7_H_ @} */
index 1003c901155e6b8990f3a3e1ee3b9518620871fd..ba2724005fa6e2fa40cb8022cc697744cfbba83b 100644 (file)
@@ -1,13 +1,5 @@
-/**
- * @file pkcs9.c
- *
- * @brief Implementation of pkcs9_t.
- *
- */
-
 /*
  * Copyright (C)2008 Andreas Steffen
- *
  * Hochschule fuer Technik Rapperswil, Switzerland
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -20,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: pkcs7.c 3423 2008-01-22 10:32:37Z andreas $
+ * $Id$
  */
 
 #include <library.h>
index 44915720cc2087f87dfb3aedebbfd1426e148b6a..e5e22bf63e6f2efced81222714ee71e771b8d148 100644 (file)
@@ -1,13 +1,5 @@
-/**
- * @file pkcs7.h
- * 
- * @brief Interface of pkcs9_t.
- * 
- */
-
 /*
-  * Copyright (C) 2008 Andreas Steffen
- *
+ * Copyright (C) 2008 Andreas Steffen
  * Hochschule fuer Technik Rapperswil, Switzerland
  *
  * This program is free software; you can redistribute it and/or modify it
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id: pkcs7.h 3423 2008-01-22 10:32:37Z andreas $
+ * $Id$
+ */
+/**
+ * @defgroup pkcs9 pkcs9
+ * @{ @ingroup crypto
  */
 
-#ifndef _PKCS9_H
-#define _PKCS9_H
+#ifndef PKCS9_H_
+#define PKCS9_H_
 
 typedef struct pkcs9_t pkcs9_t;
 
 #include <library.h>
 
 /**
- * @brief PKCS#9 .
- * 
- * @b Constructors:
- *  -pkcs9_create_from_chunk()
- *  -pkcs9_create()
- *
- * @ingroup crypto
+ * PKCS#9 attributes.
  */
 struct pkcs9_t {
+       
        /**
-        * @brief generate ASN.1 encoding of attribute list
-        *
-        * @param this                  PKCS#9 attribute list to be encoded
+        * Generate ASN.1 encoding of attribute list
         */
        void (*build_encoding) (pkcs9_t *this);
 
        /**
-        * @brief gets ASN.1 encoding of PKCS#9 attribute list
+        * Gets ASN.1 encoding of PKCS#9 attribute list
         *
-        * @param this                  calling object
         * @return                              ASN.1 encoded PKCSI#9 list
         */
        chunk_t (*get_encoding) (pkcs9_t *this);
 
        /**
-        * @brief gets a PKCS#9 attribute
+        * Gets a PKCS#9 attribute
         *
-        * @param this                  calling object
         * @param oid                   OID of the attribute
         * @return                              ASN.1 encoded value of the attribute
         */
        chunk_t (*get_attribute) (pkcs9_t *this, int oid);
 
        /**
-        * @brief adds a PKCS#9 attribute
+        * Adds a PKCS#9 attribute
         *
-        * @param this                  calling object
         * @param oid                   OID of the attribute
         * @param value                 ASN.1 encoded value of the attribute 
         */
        void (*set_attribute) (pkcs9_t *this, int oid, chunk_t value);
 
        /**
-        * @brief gets a PKCS#9 messageDigest attribute
+        * Gets a PKCS#9 messageDigest attribute
         *
-        * @param this                  calling object
         * @return                              messageDigest
         */
        chunk_t (*get_messageDigest) (pkcs9_t *this);
 
        /**
-        * @brief add a PKCS#9 messageDigest attribute
+        * Add a PKCS#9 messageDigest attribute
         *
-        * @param this                  calling object
         * @param value                 messageDigest 
         */
        void (*set_messageDigest) (pkcs9_t *this, chunk_t value);
 
        /**
-        * @brief Destroys the PKCS#9 attribute list.
-        *
-        * @param this                  PKCS#9 attribute list to destroy
+        * Destroys the PKCS#9 attribute list.
         */
        void (*destroy) (pkcs9_t *this);
 };
 
 /**
- * @brief Read a PKCS#9 attribute list from a DER encoded chunk.
+ * Read a PKCS#9 attribute list from a DER encoded chunk.
  * 
  * @param chunk                chunk containing DER encoded data
  * @param level                ASN.1 parsing start level
  * @return                     created pkcs9 attribute list, or NULL if invalid.
- * 
- * @ingroup crypto
  */
 pkcs9_t *pkcs9_create_from_chunk(chunk_t chunk, u_int level);
 
 /**
- * @brief Create an empty PKCS#9 attribute list
+ * Create an empty PKCS#9 attribute list
  * 
  * @param chunk                        chunk containing data
  * @return                             created pkcs9 attribute list.
- * 
- * @ingroup crypto
  */
 pkcs9_t *pkcs9_create(void);
 
-#endif /* _PKCS9_H */
+#endif /* PKCS9_H_ @} */
index 6bd444b1fbbc2a0ce57013c8b299be9092980c71..6b1042036d399a432f43c9bcbc2d7d0b44ae21c1 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file prf_plus.c
- * 
- * @brief Implementation of prf_plus_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
index 90f9ce2eb6cc918a94123d6d51eef9af2a163a12..9e074974cad9eb885e123510e2b3641ed8896f0b 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file prf_plus.h
- * 
- * @brief Interface for prf_plus.h.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 prf_plus prf_plus
+ * @{ @ingroup crypto
  */
 
 #ifndef PRF_PLUS_H_
@@ -29,53 +29,43 @@ typedef struct prf_plus_t prf_plus_t;
 #include <crypto/prfs/prf.h>
 
 /**
- * @brief Implementation of the prf+ function described in IKEv2 RFC.
+ * Implementation of the prf+ function described in IKEv2 RFC.
  *
  * This class implements the prf+ algorithm. Internally it uses a pseudo random
  * function, which implements the prf_t interface.
- * 
  * See IKEv2 RFC 2.13.
- * 
- * @b Constructors:
- *  - prf_plus_create()
- * 
- * @ingroup transforms
  */
 struct prf_plus_t {
        /**
-        * @brief Get pseudo random bytes.
+        * Get pseudo random bytes.
         * 
         * Get the next few bytes of the prf+ output. Space
         * must be allocated by the caller.
         * 
-        * @param this                  calling object
-        * @param length                number of bytes to get
-        * @param[out] buffer   pointer where the generated bytes will be written
+        * @param length        number of bytes to get
+        * @param buffer        pointer where the generated bytes will be written
         */
        void (*get_bytes) (prf_plus_t *this, size_t length, u_int8_t *buffer);
        
        /**
-        * @brief Allocate pseudo random bytes.
+        * Allocate pseudo random bytes.
         * 
         * Get the next few bytes of the prf+ output. This function
         * will allocate the required space.
         * 
-        * @param this                  calling object
-        * @param length                number of bytes to get
-        * @param[out] chunk    chunk which will hold generated bytes
+        * @param length        number of bytes to get
+        * @param chunk         chunk which will hold generated bytes
         */
        void (*allocate_bytes) (prf_plus_t *this, size_t length, chunk_t *chunk);
        
        /**
-        * @brief Destroys a prf_plus_t object.
-        *
-        * @param this                  calling object
+        * Destroys a prf_plus_t object.
         */
        void (*destroy) (prf_plus_t *this);
 };
 
 /**
- * @brief Creates a new prf_plus_t object.
+ * Creates a new prf_plus_t object.
  * 
  * Seed will be cloned. prf will
  * not be cloned, must be destroyed outside after
@@ -84,9 +74,7 @@ struct prf_plus_t {
  * @param prf                          prf object to use
  * @param seed                         input seed for prf
  * @return                                     prf_plus_t object
- * 
- * @ingroup transforms
  */
 prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed);
 
-#endif /*PRF_PLUS_H_*/
+#endif /*PRF_PLUS_H_ @} */
index f803829af5a7df509826d2817059e792cd7bb661..c1fa1e152012b60c33e9e201d1c451897292ae2c 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file prf.c
- * 
- * @brief Generic constructor for all prf_t
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 "prf.h"
 
-#include <crypto/hashers/hasher.h>
-#include <crypto/prfs/hmac_prf.h>
-#include <crypto/prfs/fips_prf.h>
-
 ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_FIPS_DES,
        "PRF_UNDEFINED",
        "PRF_FIPS_SHA1_160",
@@ -42,29 +32,3 @@ ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_FIP
        "PRF_HMAC_SHA2_512");
 ENUM_END(pseudo_random_function_names, PRF_HMAC_SHA2_512);
 
-/*
- * Described in header.
- */
-prf_t *prf_create(pseudo_random_function_t pseudo_random_function)
-{
-       switch (pseudo_random_function)
-       {
-               case PRF_HMAC_SHA1:
-                       return (prf_t*)hmac_prf_create(HASH_SHA1);
-               case PRF_HMAC_MD5:
-                       return (prf_t*)hmac_prf_create(HASH_MD5);
-               case PRF_HMAC_SHA2_256:
-                       return (prf_t*)hmac_prf_create(HASH_SHA256);
-               case PRF_HMAC_SHA2_384:
-                       return (prf_t*)hmac_prf_create(HASH_SHA384);
-               case PRF_HMAC_SHA2_512:
-                       return (prf_t*)hmac_prf_create(HASH_SHA512);
-               case PRF_FIPS_SHA1_160:
-                       return (prf_t*)fips_prf_create(20, g_sha1);
-               case PRF_FIPS_DES:
-               case PRF_HMAC_TIGER:
-               case PRF_AES128_CBC:
-               default:
-                       return NULL;
-       }
-}
index 8560a4a9cae2dc07d778908803d2e13025000131..662a959384eac25f912a4eb8b288a9d3f43d4287 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file prf.h
- * 
- * @brief Interface prf_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 prf prf
+ * @{ @ingroup crypto
  */
 
 #ifndef PRF_H_
@@ -30,12 +30,10 @@ typedef struct prf_t prf_t;
 #include <library.h>
 
 /**
- * @brief Pseudo random function, as in IKEv2 RFC 3.3.2.
+ * Pseudo random function, as in IKEv2 RFC 3.3.2.
  *
  * PRF algorithms not defined in IKEv2 are allocated in "private use"
  * space.
- *
- * @ingroup prfs
  */
 enum pseudo_random_function_t {
        PRF_UNDEFINED = 1024,
@@ -63,80 +61,53 @@ enum pseudo_random_function_t {
 extern enum_name_t *pseudo_random_function_names;
 
 /**
- * @brief Generic interface for pseudo-random-functions.
- * 
- * @b Constructors:
- *  - prf_create()
- *  - hmac_prf_create()
- * 
- * @todo Implement more prf algorithms
- * 
- * @ingroup prfs
+ * Generic interface for pseudo-random-functions.
  */
 struct prf_t {
        /**
-        * @brief Generates pseudo random bytes and writes them in the buffer.
+        * Generates pseudo random bytes and writes them in the buffer.
         *
-        * @param this                  calling object
-        * @param seed                  a chunk containing the seed for the next bytes
-        * @param[out] buffer   pointer where the generated bytes will be written
+        * @param seed          a chunk containing the seed for the next bytes
+        * @param buffer        pointer where the generated bytes will be written
         */
        void (*get_bytes) (prf_t *this, chunk_t seed, u_int8_t *buffer);
        
        /**
-        * @brief Generates pseudo random bytes and allocate space for them.
+        * Generates pseudo random bytes and allocate space for them.
         * 
-        * @param this                  calling object
-        * @param seed                  a chunk containing the seed for the next bytes
-        * @param[out] chunk    chunk which will hold generated bytes
+        * @param seed          a chunk containing the seed for the next bytes
+        * @param chunk         chunk which will hold generated bytes
         */
        void (*allocate_bytes) (prf_t *this, chunk_t seed, chunk_t *chunk);
        
        /**
-        * @brief Get the block size of this prf_t object.
+        * Get the block size of this prf_t object.
         * 
-        * @param this                  calling object
-        * @return                              block size in bytes
+        * @return                      block size in bytes
         */
        size_t (*get_block_size) (prf_t *this);
        
        /**
-        * @brief Get the key size of this prf_t object.
+        * Get the key size of this prf_t object.
         *
         * This is a suggestion only, all implemented PRFs accept variable key
         * length.
         * 
-        * @param this                  calling object
-        * @return                              key size in bytes
+        * @return                      key size in bytes
         */
        size_t (*get_key_size) (prf_t *this);
        
        /**
-        * @brief Set the key for this prf_t object.
+        * Set the key for this prf_t object.
         * 
-        * @param this                  calling object
-        * @param key                   key to set
+        * @param key           key to set
         */
        void (*set_key) (prf_t *this, chunk_t key);
        
        /**
-        * @brief Destroys a prf object.
-        *
-        * @param this                  calling object
+        * Destroys a prf object.
         */
        void (*destroy) (prf_t *this);
 };
 
-/**
- * @brief Generic constructor for a prf_t oject.
- * 
- * @param pseudo_random_function       Algorithm to use
- * @return
- *                                                                     - prf_t object
- *                                                                     - NULL if prf algorithm not supported
- *
- * @ingroup prfs
- */
-prf_t *prf_create(pseudo_random_function_t pseudo_random_function);
-
-#endif /*PRF_H_*/
+#endif /*PRF_H_ @} */
diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.c b/src/libstrongswan/crypto/rsa/rsa_private_key.c
deleted file mode 100644 (file)
index 43f45e4..0000000
+++ /dev/null
@@ -1,722 +0,0 @@
-/**
- * @file rsa_private_key.c
- * 
- * @brief Implementation of rsa_private_key_t.
- * 
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 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.
- *
- * RCSID $Id$
- */
-
-#include <gmp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "rsa_public_key.h"
-#include "rsa_private_key.h"
-
-#include <debug.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <utils/randomizer.h>
-
-/**
- * defined in rsa_public_key.c
- */
-extern chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e);
-extern chunk_t rsa_public_key_id_create(const mpz_t n, const mpz_t e);
-
-/**
- *  Public exponent to use for key generation.
- */
-#define PUBLIC_EXPONENT 0x10001
-
-typedef struct private_rsa_private_key_t private_rsa_private_key_t;
-
-/**
- * Private data of a rsa_private_key_t object.
- */
-struct private_rsa_private_key_t {
-       /**
-        * Public interface for this signer.
-        */
-       rsa_private_key_t public;
-       
-       /**
-        * Version of key, as encoded in PKCS#1
-        */
-       u_int version;
-       
-       /**
-        * Public modulus.
-        */
-       mpz_t n;
-       
-       /**
-        * Public exponent.
-        */
-       mpz_t e;
-       
-       /**
-        * Private prime 1.
-        */
-       mpz_t p;
-       
-       /**
-        * Private Prime 2.
-        */
-       mpz_t q;
-       
-       /**
-        * Private exponent.
-        */
-       mpz_t d;
-       
-       /**
-        * Private exponent 1.
-        */
-       mpz_t exp1;
-       
-       /**
-        * Private exponent 2.
-        */
-       mpz_t exp2;
-       
-       /**
-        * Private coefficient.
-        */
-       mpz_t coeff;
-       
-       /**
-        * Keysize in bytes.
-        */
-       size_t k;
-
-       /**
-        * Keyid formed as a SHA-1 hash of a publicKeyInfo object
-        */
-       chunk_t keyid;
-       
-       /**
-        * @brief Implements the RSADP algorithm specified in PKCS#1.
-        * 
-        * @param this          calling object
-        * @param data          data to process
-        * @return                      processed data
-        */
-       chunk_t (*rsadp) (private_rsa_private_key_t *this, chunk_t data);
-               
-       /**
-        * @brief Implements the RSASP1 algorithm specified in PKCS#1.
-        * @param this          calling object
-        * @param data          data to process
-        * @return                      processed data
-        */
-       chunk_t (*rsasp1) (private_rsa_private_key_t *this, chunk_t data);
-};
-
-/* ASN.1 definition of a PKCS#1 RSA private key */
-static const asn1Object_t privkey_objects[] = {
-       { 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 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
-#define PRIV_KEY_ROOF                  16
-
-/**
- * Auxiliary function overwriting private key material with
- * pseudo-random bytes before releasing it
- */
-static void mpz_clear_randomized(mpz_t z)
-{
-       size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
-       u_int8_t *random_bytes = alloca(len);
-
-       randomizer_t *randomizer = randomizer_create();
-       
-       randomizer->get_pseudo_random_bytes(randomizer, len, random_bytes);
-
-       /* overwrite mpz_t with pseudo-random bytes before clearing it */
-       mpz_import(z, len, 1, 1, 1, 0, random_bytes);
-       mpz_clear(z);
-
-       randomizer->destroy(randomizer);
-}
-
-/**
- * Generate a random prime number with prime_len bytes
- */
-static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_len, mpz_t *prime)
-{
-       randomizer_t *randomizer;
-       chunk_t random_bytes;
-       status_t status;
-       
-       randomizer = randomizer_create();
-       mpz_init(*prime);
-       
-       do
-       {
-               DBG1("  generating %d bit prime from %s ...", BITS_PER_BYTE * prime_len, DEV_RANDOM);
-               status = randomizer->allocate_random_bytes(randomizer, prime_len, &random_bytes);
-               if (status != SUCCESS)
-               {
-                       randomizer->destroy(randomizer);
-                       mpz_clear(*prime);
-                       return FAILED;
-               }
-               
-               /* make sure most significant bit is set */
-               random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80;
-               
-               /* convert chunk to mpz value */
-               mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
-               
-               /* get next prime */
-               mpz_nextprime (*prime, *prime);
-               
-               /* free the random_bytes after overwriting them with a pseudo-random sequence */
-               chunk_free_randomized(&random_bytes);
-       }
-       /* check if it isnt too large */
-       while (((mpz_sizeinbase(*prime, 2) + 7) / BITS_PER_BYTE) > prime_len);
-       
-       randomizer->destroy(randomizer);
-       return SUCCESS;
-}
-
-/**
- * Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1.
- */
-static chunk_t rsadp(private_rsa_private_key_t *this, chunk_t data)
-{
-       mpz_t t1, t2;
-       chunk_t decrypted;
-       
-       mpz_init(t1);
-       mpz_init(t2);
-       
-       mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
-       
-       mpz_powm(t2, t1, this->exp1, this->p);  /* m1 = c^dP mod p */
-       mpz_powm(t1, t1, this->exp2, this->q);  /* m2 = c^dQ mod Q */
-       mpz_sub(t2, t2, t1);                                    /* h = qInv (m1 - m2) mod p */
-       mpz_mod(t2, t2, this->p);
-       mpz_mul(t2, t2, this->coeff);
-       mpz_mod(t2, t2, this->p);
-       
-       mpz_mul(t2, t2, this->q);                               /* m = m2 + h q */
-       mpz_add(t1, t1, t2);
-       
-       decrypted.len = this->k;
-       decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
-       
-       mpz_clear_randomized(t1);
-       mpz_clear_randomized(t2);
-       
-       return decrypted;
-}
-
-/**
- * Implementation of rsa_private_key_t.pkcs1_decrypt.
- */
-static status_t pkcs1_decrypt(private_rsa_private_key_t *this,
-                                                         chunk_t in, chunk_t *out)
-{
-       status_t status = FAILED;
-       chunk_t em, em_ori;
-
-       /* decrypt the input data */
-       em = em_ori = this->rsadp(this, in);
-
-       /* PKCS#1 v1.5 EME encryption formatting
-        * EM = 00 || 02 || PS || 00 || M
-        * PS = pseudo-random nonzero octets
-        */
-
-       /* check for magic bytes */
-       if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x02)
-       {
-               DBG1("incorrect padding - probably wrong RSA key");
-               goto end;
-       }
-       em.ptr += 2;
-       em.len -= 2;
-
-       /* the plaintext data starts after first 0x00 byte */
-       while (em.len-- > 0 && *em.ptr++ != 0x00);
-
-       if (em.len == 0)
-       {
-               DBG1("no plaintext data found");
-               goto end;
-       }
-
-    *out = chunk_clone(em);
-    status = SUCCESS;
-
-end:
-       free(em_ori.ptr);
-       return status;
-}
-
-/**
- * Implementation of rsa_private_key_t.build_emsa_pkcs1_signature.
- */
-static status_t build_emsa_pkcs1_signature(private_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)
-       {
-               return NOT_SUPPORTED;
-       }
-
-       /* get hasher */
-       hasher = hasher_create(hash_algorithm);
-       if (hasher == NULL)
-       {
-               return NOT_SUPPORTED;   
-       }
-       
-       /* 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
-        * T = encoded_hash
-        */
-       em.len = this->k;
-       em.ptr = malloc(em.len);
-       
-       /* fill em with padding */
-       memset(em.ptr, 0xFF, em.len);
-       /* set magic bytes */
-       *(em.ptr) = 0x00;
-       *(em.ptr+1) = 0x01;
-       *(em.ptr + em.len - digestInfo.len - 1) = 0x00;
-       /* set DER-encoded hash */
-       memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
-
-       /* build signature */
-       *signature = this->rsasp1(this, em);
-       
-       free(digestInfo.ptr);
-       free(em.ptr);
-       
-       return SUCCESS; 
-}
-
-/**
- * Implementation of rsa_private_key_t.pkcs1_write.
- */
-static bool pkcs1_write(private_rsa_private_key_t *this, const char *filename, bool force)
-{
-       bool status;
-
-    chunk_t pkcs1 = asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm",
-                                               ASN1_INTEGER_0,
-                                               asn1_integer_from_mpz(this->n),
-                                               asn1_integer_from_mpz(this->e),
-                                               asn1_integer_from_mpz(this->d),
-                                               asn1_integer_from_mpz(this->p),
-                                               asn1_integer_from_mpz(this->q),
-                                               asn1_integer_from_mpz(this->exp1),
-                                               asn1_integer_from_mpz(this->exp2),
-                                               asn1_integer_from_mpz(this->coeff));
-
-       status = chunk_write(pkcs1, filename, "pkcs1", 0066, force);
-       chunk_free_randomized(&pkcs1);
-       return status;
-}
-
-/**
- * Implementation of rsa_private_key_t.get_public_key.
- */
-rsa_public_key_t *get_public_key(private_rsa_private_key_t *this)
-{
-       return rsa_public_key_create(this->n, this->e);
-}
-
-/**
- * Implementation of rsa_private_key.belongs_to.
- */
-static bool belongs_to(private_rsa_private_key_t *this, rsa_public_key_t *public)
-{
-       return chunk_equals(this->keyid, public->get_keyid(public));
-}
-
-/**
- * Check the loaded key if it is valid and usable
- * TODO: Log errors
- */
-static status_t check(private_rsa_private_key_t *this)
-{
-       mpz_t t, u, q1;
-       status_t status = SUCCESS;
-       
-       /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
-       * We actually require more (for security).
-       */
-       if (this->k < 512 / BITS_PER_BYTE)
-       {
-               return FAILED;
-       }
-       
-       /* we picked a max modulus size to simplify buffer allocation */
-       if (this->k > 8192 / BITS_PER_BYTE)
-       {
-               return FAILED;
-       }
-       
-       mpz_init(t);
-       mpz_init(u);
-       mpz_init(q1);
-       
-       /* check that n == p * q */
-       mpz_mul(u, this->p, this->q);
-       if (mpz_cmp(u, this->n) != 0)
-       {
-               status = FAILED;
-       }
-       
-       /* check that e divides neither p-1 nor q-1 */
-       mpz_sub_ui(t, this->p, 1);
-       mpz_mod(t, t, this->e);
-       if (mpz_cmp_ui(t, 0) == 0)
-       {
-               status = FAILED;
-       }
-       
-       mpz_sub_ui(t, this->q, 1);
-       mpz_mod(t, t, this->e);
-       if (mpz_cmp_ui(t, 0) == 0)
-       {
-               status = FAILED;
-       }
-       
-       /* 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, this->q, 1);
-       mpz_sub_ui(u, this->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, this->d, this->e);
-       mpz_mod(t, t, u);
-       if (mpz_cmp_ui(t, 1) != 0)
-       {
-               status = FAILED;
-       }
-       
-       /* check that exp1 is d mod (p-1) */
-       mpz_sub_ui(u, this->p, 1);
-       mpz_mod(t, this->d, u);
-       if (mpz_cmp(t, this->exp1) != 0)
-       {
-               status = FAILED;
-       }
-       
-       /* check that exp2 is d mod (q-1) */
-       mpz_sub_ui(u, this->q, 1);
-       mpz_mod(t, this->d, u);
-       if (mpz_cmp(t, this->exp2) != 0)
-       {
-               status = FAILED;
-       }
-       
-       /* check that coeff is (q^-1) mod p */
-       mpz_mul(t, this->coeff, this->q);
-       mpz_mod(t, t, this->p);
-       if (mpz_cmp_ui(t, 1) != 0)
-       {
-               status = FAILED;
-       }
-       
-       mpz_clear_randomized(t);
-       mpz_clear_randomized(u);
-       mpz_clear_randomized(q1);
-       return status;
-}
-
-/**
- * Implementation of rsa_private_key.destroy.
- */
-static void destroy(private_rsa_private_key_t *this)
-{
-       mpz_clear_randomized(this->n);
-       mpz_clear_randomized(this->e);
-       mpz_clear_randomized(this->p);
-       mpz_clear_randomized(this->q);
-       mpz_clear_randomized(this->d);
-       mpz_clear_randomized(this->exp1);
-       mpz_clear_randomized(this->exp2);
-       mpz_clear_randomized(this->coeff);
-       chunk_free_randomized(&this->keyid);
-       free(this);
-}
-
-/**
- * Internal generic constructor
- */
-static private_rsa_private_key_t *rsa_private_key_create_empty(void)
-{
-       private_rsa_private_key_t *this = malloc_thing(private_rsa_private_key_t);
-       
-       /* public functions */
-       this->public.pkcs1_decrypt = (status_t (*) (rsa_private_key_t*,chunk_t,chunk_t*))pkcs1_decrypt;
-       this->public.build_emsa_pkcs1_signature = (status_t (*) (rsa_private_key_t*,hash_algorithm_t,chunk_t,chunk_t*))build_emsa_pkcs1_signature;
-       this->public.pkcs1_write = (bool (*) (rsa_private_key_t*,const char*,bool))pkcs1_write;
-       this->public.get_public_key = (rsa_public_key_t* (*) (rsa_private_key_t*))get_public_key;
-       this->public.belongs_to = (bool (*) (rsa_private_key_t*,rsa_public_key_t*))belongs_to;
-       this->public.destroy = (void (*) (rsa_private_key_t*))destroy;
-       
-       /* private functions */
-       this->rsadp = rsadp;
-       this->rsasp1 = rsadp; /* same algorithm */
-       
-       this->keyid = chunk_empty;
-       
-       return this;
-}
-
-/*
- * See header
- */
-rsa_private_key_t *rsa_private_key_create(size_t key_size)
-{
-       mpz_t p, q, n, e, d, exp1, exp2, coeff;
-       mpz_t m, q1, t;
-       private_rsa_private_key_t *this;
-       size_t key_len = key_size / BITS_PER_BYTE;
-       size_t prime_len = key_len / 2;
-       
-       /* Get values of primes p and q  */
-       if (compute_prime(this, prime_len, &p) != SUCCESS)
-       {
-               return NULL;
-       }       
-       if (compute_prime(this, prime_len, &q) != SUCCESS)
-       {
-               mpz_clear(p);
-               return NULL;
-       }
-       
-       mpz_init(t);    
-       mpz_init(n);
-       mpz_init(d);
-       mpz_init(exp1);
-       mpz_init(exp2);
-       mpz_init(coeff);
-       
-       /* Swapping Primes so p is larger then q */
-       if (mpz_cmp(p, q) < 0)
-       {
-               mpz_swap(p, q);
-       }
-       
-       mpz_mul(n, p, q);                                               /* n = p*q */
-       mpz_init_set_ui(e, PUBLIC_EXPONENT);    /* assign public exponent */
-       mpz_init_set(m, p);                                     /* m = p */
-       mpz_sub_ui(m, m, 1);                                    /* m = m -1 */
-       mpz_init_set(q1, q);                                    /* q1 = q */
-       mpz_sub_ui(q1, q1, 1);                                  /* q1 = q1 -1 */
-       mpz_gcd(t, m, q1);                                              /* t = gcd(p-1, q-1) */
-       mpz_mul(m, m, q1);                                              /* m = (p-1)*(q-1) */
-       mpz_divexact(m, m, t);                                  /* m = m / t */
-       mpz_gcd(t, m, e);                                               /* t = gcd(m, e) (greatest common divisor) */
-
-       mpz_invert(d, e, m);                                    /* e has an inverse mod m */
-       if (mpz_cmp_ui(d, 0) < 0)                               /* make sure d is positive */
-       {
-               mpz_add(d, d, m);
-       }
-       mpz_sub_ui(t, p, 1);                                    /* t = p-1 */
-       mpz_mod(exp1, d, t);                                    /* exp1 = d mod p-1 */
-       mpz_sub_ui(t, q, 1);                                    /* t = q-1 */
-       mpz_mod(exp2, d, t);                                    /* exp2 = d mod q-1 */
-       
-       mpz_invert(coeff, q, p);                                /* coeff = q^-1 mod p */
-       if (mpz_cmp_ui(coeff, 0) < 0)                   /* make coeff d is positive */
-       {
-               mpz_add(coeff, coeff, p);
-       }
-
-       mpz_clear_randomized(q1);
-       mpz_clear_randomized(m);
-       mpz_clear_randomized(t);
-
-       /* determine exact the modulus size in bits */
-       key_size = mpz_sizeinbase(n, 2);
-
-       /* create and fill in rsa_private_key_t object */
-       this = rsa_private_key_create_empty();
-       this->k = (key_size + 7) / BITS_PER_BYTE;
-       this->keyid = rsa_public_key_id_create(n, e);
-       *(this->p) = *p;
-       *(this->q) = *q;
-       *(this->n) = *n;
-       *(this->e) = *e;
-       *(this->d) = *d;
-       *(this->exp1) = *exp1;
-       *(this->exp2) = *exp2;
-       *(this->coeff) = *coeff;
-       DBG1("generated %d bit RSA key with keyid: %#B", key_size, &this->keyid);
-
-       return &this->public;
-}
-
-/*
- * see header
- */
-rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-       private_rsa_private_key_t *this;
-       
-       this = 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);
-       
-       asn1_init(&ctx, blob, 0, FALSE, TRUE);
-       
-       while (objectID < PRIV_KEY_ROOF) 
-       {
-               if (!extract_object(privkey_objects, &objectID, &object, &level, &ctx))
-               {
-                       destroy(this);
-                       return FALSE;
-               }
-               switch (objectID)
-               {
-                       case PRIV_KEY_VERSION:
-                               if (object.len > 0 && *object.ptr != 0)
-                               {
-                                       destroy(this);
-                                       return NULL;
-                               }
-                               break;
-                       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->p, object.len, 1, 1, 1, 0, object.ptr);
-                               break;
-                       case PRIV_KEY_PRIME2:
-                               mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
-                               break;
-                       case PRIV_KEY_EXP1:
-                               mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr);
-                               break;
-                       case PRIV_KEY_EXP2:
-                               mpz_import(this->exp2, 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;
-               }
-               objectID++;
-       }
-       
-       this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
-       this->keyid = rsa_public_key_id_create(this->n, this->e);
-
-       if (check(this) != SUCCESS)
-       {
-               destroy(this);
-               return NULL;
-       }
-       else
-       {
-               return &this->public;
-       }
-}
-
-/*
- * see header
- */
-rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase)
-{
-       bool pgp = FALSE;
-       chunk_t chunk = chunk_empty;
-       rsa_private_key_t *key = NULL;
-
-       if (!pem_asn1_load_file(filename, passphrase, "private key", &chunk, &pgp))
-               return NULL;
-
-       key = rsa_private_key_create_from_chunk(chunk);
-       chunk_free_randomized(&chunk);
-       return key;
-}
diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.h b/src/libstrongswan/crypto/rsa/rsa_private_key.h
deleted file mode 100644 (file)
index 5f66458..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * @file rsa_private_key.h
- * 
- * @brief Interface of rsa_private_key_t.
- * 
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 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.
- *
- * RCSID $Id$
- */
-
-#ifndef RSA_PRIVATE_KEY_H_
-#define RSA_PRIVATE_KEY_H_
-
-typedef struct rsa_private_key_t rsa_private_key_t;
-
-#include <library.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief RSA private key with associated functions.
- *
- * Currently only supports signing using EMSA encoding.
- *
- * @b Constructors:
- *  - rsa_private_key_create()
- *  - rsa_private_key_create_from_chunk()
- *  - rsa_private_key_create_from_file()
- * 
- * @see rsa_public_key_t
- *
- * @ingroup rsa
- */
-struct rsa_private_key_t {
-
-       /**
-        * @brief Decrypt a data block based on EME-PKCS1 encoding.
-        * 
-        * 
-        * @param this                          calling object
-        * @param data                          encrypted input data
-        * @param out                           decrypted output data
-        * @return
-        *                                                      - SUCCESS
-        *                                                      - FAILED if padding is not correct
-        */
-       status_t (*pkcs1_decrypt) (rsa_private_key_t *this, chunk_t in, chunk_t *out);
-
-       /**
-        * @brief Build a signature over a chunk using EMSA-PKCS1 encoding.
-        * 
-        * This signature creates a hash using the specified hash algorithm, concatenates
-        * it with an ASN1-OID of the hash algorithm and runs the RSASP1 function
-        * on it.
-        * 
-        * @param this                          calling object
-        * @param hash_algorithm        hash algorithm to use for hashing
-        * @param data                          data to sign
-        * @param[out] signature        allocated signature
-        * @return
-        *                                                      - SUCCESS
-        *                                                      - INVALID_STATE, if key not set
-        *                                                      - NOT_SUPPORTED, if hash algorithm not supported
-        */
-       status_t (*build_emsa_pkcs1_signature) (rsa_private_key_t *this, hash_algorithm_t hash_algorithm, chunk_t data, chunk_t *signature);
-       
-       /**
-        * @brief Writes an RSA private key to a file in PKCS#1 format.
-        *
-        * @param this                          calling object
-        * @param filename                      file to which the key should be written.
-        * @param force                         if TRUE overwrite existing file
-        * @return                                      TRUE if successful - FALSE otherwise
-        */
-       bool (*pkcs1_write) (rsa_private_key_t *this, const char *filename, bool force);
-       
-       /**
-        * @brief Create a rsa_public_key_t with the public part of the key.
-        * 
-        * @param this                          calling object
-        * @return                                      public_key
-        */
-       rsa_public_key_t *(*get_public_key) (rsa_private_key_t *this);
-       
-       /**
-        * @brief Check if a private key belongs to a public key.
-        * 
-        * Compares the public part of the private key with the
-        * public key, return TRUE if it equals.
-        * 
-        * @param this                          private key
-        * @param public                        public key
-        * @return                                      TRUE, if keys belong together
-        */
-       bool (*belongs_to) (rsa_private_key_t *this, rsa_public_key_t *public);
-       
-       /**
-        * @brief Destroys the private key.
-        * 
-        * @param this                          private key to destroy
-        */
-       void (*destroy) (rsa_private_key_t *this);
-};
-
-/**
- * @brief Generate a new RSA key with specified key length.
- * 
- * @param key_size                     size of the key in bits
- * @return                                     generated rsa_private_key_t.
- * 
- * @ingroup rsa
- */
-rsa_private_key_t *rsa_private_key_create(size_t key_size);
-
-/**
- * @brief Load an RSA private key from a chunk.
- * 
- * Load a key from a chunk, encoded as described in PKCS#1
- * (ASN1 DER encoded).
- * 
- * @param chunk                                chunk containing the DER encoded key
- * @return                                     loaded rsa_private_key_t, or NULL
- * 
- * @ingroup rsa
- */
-rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Load an RSA private key from a file.
- * 
- * Load a key from a file, which is either in a unencrypted binary
- * format (DER), or in a (encrypted) PEM format. The supplied 
- * passphrase is used to decrypt an ecrypted key.
- * 
- * @param filename                     filename which holds the key
- * @param passphrase           optional passphase for decryption, can be NULL
- * @return                                     loaded rsa_private_key_t, or NULL
- * 
- * @todo Implement PEM file loading
- * @todo Implement key decryption
- * 
- * @ingroup rsa
- */
-rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase);
-
-#endif /*RSA_PRIVATE_KEY_H_*/
diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.c b/src/libstrongswan/crypto/rsa/rsa_public_key.c
deleted file mode 100644 (file)
index 16ac3bb..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-/**
- * @file rsa_public_key.c
- * 
- * @brief Implementation of rsa_public_key_t.
- * 
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 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.
- *
- * RCSID $Id$
- */
-#include <gmp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "rsa_public_key.h"
-
-#include <debug.h>
-#include <utils/randomizer.h>
-#include <crypto/hashers/hasher.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-
-/* 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 */
-};
-
-#define PUB_KEY_RSA_PUBLIC_KEY         0
-#define PUB_KEY_MODULUS                                1
-#define PUB_KEY_EXPONENT                       2
-#define PUB_KEY_ROOF                           3
-
-/* ASN.1 definition of digestInfo */
-static const asn1Object_t digestInfoObjects[] = {
-       { 0, "digestInfo",                      ASN1_SEQUENCE,          ASN1_OBJ  }, /*  0 */
-       { 1,   "digestAlgorithm",       ASN1_EOC,                       ASN1_RAW  }, /*  1 */
-       { 1,   "digest",                        ASN1_OCTET_STRING,      ASN1_BODY }, /*  2 */
-};
-
-#define DIGEST_INFO                                    0
-#define DIGEST_INFO_ALGORITHM          1
-#define DIGEST_INFO_DIGEST                     2
-#define DIGEST_INFO_ROOF                       3
-
-typedef struct private_rsa_public_key_t private_rsa_public_key_t;
-
-/**
- * Private data structure with signing context.
- */
-struct private_rsa_public_key_t {
-       /**
-        * Public interface for this signer.
-        */
-       rsa_public_key_t public;
-       
-       /**
-        * Public modulus.
-        */
-       mpz_t n;
-       
-       /**
-        * Public exponent.
-        */
-       mpz_t e;
-       
-       /**
-        * Keysize in bytes.
-        */
-       size_t k;
-       
-       /**
-        * Keyid formed as a SHA-1 hash of a publicKeyInfo object
-        */
-       chunk_t keyid;
-
-       /**
-        * @brief Implements the RSAEP algorithm specified in PKCS#1.
-        * 
-        * @param this          calling object
-        * @param data          data to process
-        * @return                      processed data
-        */
-       chunk_t (*rsaep) (const private_rsa_public_key_t *this, chunk_t data);
-               
-       /**
-        * @brief Implements the RSASVP1 algorithm specified in PKCS#1.
-        * 
-        * @param this          calling object
-        * @param data          data to process
-        * @return                      processed data
-        */
-       chunk_t (*rsavp1) (const private_rsa_public_key_t *this, chunk_t data);
-};
-
-/**
- * Implementation of private_rsa_public_key_t.rsaep and private_rsa_public_key_t.rsavp1
- */
-static chunk_t rsaep(const private_rsa_public_key_t *this, chunk_t data)
-{
-       mpz_t m, c;
-       chunk_t encrypted;
-       
-       mpz_init(c);
-       mpz_init(m);
-       
-       mpz_import(m, data.len, 1, 1, 1, 0, data.ptr);
-       
-       mpz_powm(c, m, this->e, this->n);
-
-    encrypted.len = this->k;
-    encrypted.ptr = mpz_export(NULL, NULL, 1, encrypted.len, 1, 0, c);
-       
-       mpz_clear(c);
-       mpz_clear(m);   
-       
-       return encrypted;
-}
-
-/**
- * Implementation of rsa_public_key_t.eme_pkcs1_encrypt.
- */
-static status_t pkcs1_encrypt(private_rsa_public_key_t *this,
-                                                         chunk_t in, chunk_t *out)
-{
-       chunk_t em;
-       u_char *pos;
-       int padding = this->k - in.len - 3;
-
-       if (padding < 8)
-       {
-               DBG1("rsa padding of %d bytes is too small", padding);
-               return FAILED;
-       }
-       em.len = this->k;
-       em.ptr = pos = malloc(em.len);
-       
-       /* add padding according to PKCS#1 7.2.1 1.+2. */
-       *pos++ = 0x00;
-    *pos++ = 0x02;
-
-    /* pad with pseudo random bytes unequal to zero */
-       {
-               randomizer_t *randomizer = randomizer_create();
-
-           /* pad with pseudo random bytes unequal to zero */
-               while (padding--)
-               {
-                       randomizer->get_pseudo_random_bytes(randomizer, 1, pos);
-                       while (!*pos)
-                       {
-                               randomizer->get_pseudo_random_bytes(randomizer, 1, pos);
-                       }
-                       pos++;
-               }
-               randomizer->destroy(randomizer);
-       }
-
-       /* append the padding terminator */
-       *pos++ = 0x00;
-
-       /* now add the data */
-       memcpy(pos, in.ptr, in.len);
-       *out = this->rsaep(this, em);
-       free(em.ptr);
-       return SUCCESS;
-}
-
-/**
- * Implementation of rsa_public_key.verify_emsa_pkcs1_signature.
- */
-static status_t verify_emsa_pkcs1_signature(const private_rsa_public_key_t *this,
-                                                                                       hash_algorithm_t algorithm,
-                                                                                       chunk_t data, chunk_t signature)
-{
-       chunk_t em_ori, em;
-       status_t res = FAILED;
-       
-       /* remove any preceding 0-bytes from signature */
-       while (signature.len && *(signature.ptr) == 0x00)
-       {
-               signature.len -= 1;
-               signature.ptr++;
-       }
-       
-       if (signature.len > this->k)
-       {
-               return INVALID_ARG;
-       }
-       
-       /* unpack signature */
-       em_ori = em = this->rsavp1(this, signature);
-       
-       /* result should look like this:
-        * EM = 0x00 || 0x01 || PS || 0x00 || T. 
-        * PS = 0xFF padding, with length to fill em
-        * T = oid || hash
-        */
-       
-       /* check magic bytes */
-       if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
-       {
-               DBG2("incorrect padding - probably wrong RSA key");
-               goto end;
-       }
-       em.ptr += 2;
-       em.len -= 2;
-       
-       /* find magic 0x00 */
-       while (em.len > 0)
-       {
-               if (*em.ptr == 0x00)
-               {
-                       /* found magic byte, stop */
-                       em.ptr++;
-                       em.len--;
-                       break;
-               }
-               else if (*em.ptr != 0xFF)
-               {
-                       /* bad padding, decryption failed ?!*/
-                       goto end;
-               }
-               em.ptr++;
-               em.len--;
-       }
-
-       if (em.len == 0)
-       {
-               /* no digestInfo found */
-               goto end;
-       }
-
-       /* parse ASN.1-based digestInfo */
-       {
-               asn1_ctx_t ctx;
-               chunk_t object;
-               u_int level;
-               int objectID = 0;
-               hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
-
-               asn1_init(&ctx, em, 0, FALSE, FALSE);
-
-               while (objectID < DIGEST_INFO_ROOF)
-               {
-                       if (!extract_object(digestInfoObjects, &objectID, &object, &level, &ctx))
-                       {
-                               goto end;
-                       }
-                       switch (objectID)
-                       {
-                               case DIGEST_INFO:
-                                       if (em.len > object.len)
-                                       {
-                                               DBG1("digestInfo field in signature is followed by %u surplus bytes",
-                                                        em.len - object.len);
-                                               goto end;
-                                       }
-                                       break;
-                               case DIGEST_INFO_ALGORITHM:
-                                       {
-                                               int hash_oid = parse_algorithmIdentifier(object, level+1, NULL);
-
-                                               hash_algorithm = hasher_algorithm_from_oid(hash_oid);
-                                               if (hash_algorithm == HASH_UNKNOWN
-                                               || (algorithm != HASH_UNKNOWN && hash_algorithm != algorithm))
-                                               {
-                                                       DBG1("wrong hash algorithm used in signature");
-                                                       goto end;
-                                               }
-                                       }
-                                       break;
-                               case DIGEST_INFO_DIGEST:
-                                       {
-                                               chunk_t hash;
-                                               hasher_t *hasher = hasher_create(hash_algorithm);
-
-                                               if (object.len != hasher->get_hash_size(hasher))
-                                               {
-                                                       DBG1("hash size in signature is %u bytes instead of %u bytes",
-                                                                object.len, hasher->get_hash_size(hasher));
-                                                       hasher->destroy(hasher);
-                                                       goto end;
-                                               }
-
-                                               /* build our own hash */
-                                               hasher->allocate_hash(hasher, data, &hash);
-                                               hasher->destroy(hasher);
-       
-                                               /* compare the hashes */
-                                               res = memeq(object.ptr, hash.ptr, hash.len) ? SUCCESS : FAILED;
-                                               free(hash.ptr);
-                                       }
-                                       break;
-                               default:
-                                       break;
-                       }
-                       objectID++;
-               }
-       }
-
-end:
-       free(em_ori.ptr);
-       return res;
-}
-
-
-/**
- * Implementation of rsa_public_key_t.get_modulus.
- */
-static mpz_t *get_modulus(const private_rsa_public_key_t *this)
-{
-       return (mpz_t*)&this->n;
-}
-
-/**
- * Implementation of rsa_public_key_t.get_keysize.
- */
-static size_t get_keysize(const private_rsa_public_key_t *this)
-{
-       return this->k;
-}
-
-/**
- * Build a DER-encoded publicKeyInfo object from an RSA public key.
- * Also used in rsa_private_key.c.
- */
-chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e)
-{
-       chunk_t publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
-                                                                asn1_integer_from_mpz(n),
-                                                                asn1_integer_from_mpz(e));
-
-       return asn1_wrap(ASN1_SEQUENCE, "cm",
-                               asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
-                               asn1_bitstring("m", publicKey));
-}
-
-/**
- * Form the RSA keyid as a SHA-1 hash of a publicKeyInfo object
- * Also used in rsa_private_key.c.
- */
-chunk_t rsa_public_key_id_create(mpz_t n, mpz_t e)
-{
-       chunk_t keyid;
-       chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(n, e);
-       hasher_t *hasher = hasher_create(HASH_SHA1);
-
-       hasher->allocate_hash(hasher, publicKeyInfo, &keyid);
-       hasher->destroy(hasher);
-       free(publicKeyInfo.ptr);
-
-       return keyid;
-}
-
-/**
- * Implementation of rsa_public_key_t.get_publicKeyInfo.
- */
-static chunk_t get_publicKeyInfo(const private_rsa_public_key_t *this)
-{
-       return rsa_public_key_info_to_asn1(this->n, this->e);
-}
-
-/**
- * Implementation of rsa_public_key_t.get_keyid.
- */
-static chunk_t get_keyid(const private_rsa_public_key_t *this)
-{
-       return this->keyid;
-}
-
-/* forward declaration used by rsa_public_key_t.clone */
-private_rsa_public_key_t *rsa_public_key_create_empty(void);
-
-/**
- * Implementation of rsa_public_key_t.clone.
- */
-static rsa_public_key_t* _clone(const private_rsa_public_key_t *this)
-{
-       private_rsa_public_key_t *clone = rsa_public_key_create_empty();
-       
-       mpz_init_set(clone->n, this->n);
-       mpz_init_set(clone->e, this->e);
-       clone->keyid = chunk_clone(this->keyid);
-       clone->k = this->k;
-       
-       return &clone->public;
-}
-
-/**
- * Implementation of rsa_public_key_t.destroy.
- */
-static void destroy(private_rsa_public_key_t *this)
-{
-       mpz_clear(this->n);
-       mpz_clear(this->e);
-       free(this->keyid.ptr);
-       free(this);
-}
-
-/**
- * Generic private constructor
- */
-private_rsa_public_key_t *rsa_public_key_create_empty(void)
-{
-       private_rsa_public_key_t *this = malloc_thing(private_rsa_public_key_t);
-       
-       /* public functions */
-       this->public.pkcs1_encrypt = (status_t (*) (rsa_public_key_t*,chunk_t,chunk_t*))pkcs1_encrypt;
-       this->public.verify_emsa_pkcs1_signature = (status_t (*) (const rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t))verify_emsa_pkcs1_signature;
-       this->public.get_modulus = (mpz_t *(*) (const rsa_public_key_t*))get_modulus;
-       this->public.get_keysize = (size_t (*) (const rsa_public_key_t*))get_keysize;
-       this->public.get_publicKeyInfo = (chunk_t (*) (const rsa_public_key_t*))get_publicKeyInfo;
-       this->public.get_keyid = (chunk_t (*) (const rsa_public_key_t*))get_keyid;
-       this->public.clone = (rsa_public_key_t* (*) (const rsa_public_key_t*))_clone;
-       this->public.destroy = (void (*) (rsa_public_key_t*))destroy;
-       
-       /* private functions */
-       this->rsaep = rsaep;
-       this->rsavp1 = rsaep; /* same algorithm */
-       
-       return this;
-}
-
-/*
- * See header
- */
-rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e)
-{
-       private_rsa_public_key_t *this = rsa_public_key_create_empty();
-
-       mpz_init_set(this->n, n);
-       mpz_init_set(this->e, e);
-
-       this->k = (mpz_sizeinbase(n, 2) + 7) / BITS_PER_BYTE;
-       this->keyid = rsa_public_key_id_create(n, e);
-       return &this->public;
-}
-/*
- * See header
- */
-rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t blob)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-
-       private_rsa_public_key_t *this = rsa_public_key_create_empty();
-
-       mpz_init(this->n);
-       mpz_init(this->e);
-       
-       asn1_init(&ctx, blob, 0, FALSE, FALSE);
-       
-       while (objectID < PUB_KEY_ROOF) 
-       {
-               if (!extract_object(pubkeyObjects, &objectID, &object, &level, &ctx))
-               {
-                       destroy(this);
-                       return FALSE;
-               }
-               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;
-               }
-               objectID++;
-       }
-
-       this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
-       this->keyid = rsa_public_key_id_create(this->n, this->e);
-       return &this->public;
-}
-
-/*
- * See header
- */
-rsa_public_key_t *rsa_public_key_create_from_file(char *filename)
-{
-       bool pgp = FALSE;
-       chunk_t chunk = chunk_empty;
-       rsa_public_key_t *pubkey = NULL;
-
-       if (!pem_asn1_load_file(filename, NULL, "public key", &chunk, &pgp))
-       {
-               return NULL;
-       }
-       pubkey = rsa_public_key_create_from_chunk(chunk);
-       free(chunk.ptr);
-       return pubkey;
-}
diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.h b/src/libstrongswan/crypto/rsa/rsa_public_key.h
deleted file mode 100644 (file)
index 1c15169..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * @file rsa_public_key.h
- * 
- * @brief Interface of rsa_public_key_t.
- * 
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 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.
- *
- * RCSID $Id$
- */
-
-#ifndef RSA_PUBLIC_KEY_H_
-#define RSA_PUBLIC_KEY_H_
-
-typedef struct rsa_public_key_t rsa_public_key_t;
-
-#include <gmp.h>
-
-#include <library.h>
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief RSA public key with associated functions.
- * 
- * Currently only supports signature verification using
- * the EMSA encoding (see PKCS1)
- * 
- * @b Constructors:
- * - rsa_public_key_create()
- * - rsa_public_key_create_from_chunk()
- * - rsa_public_key_create_from_file()
- *
- * @ingroup rsa
- */
-struct rsa_public_key_t {
-
-       /**
-        * @brief Encrypt a data block using EME-PKCS1 encoding.
-        * 
-        * 
-        * @param this                          calling object
-        * @param data                          plaintext input data
-        * @param out                           encrypted output data
-        * @return
-        *                                                      - SUCCESS
-        *                                                      - FAILED if data block is too large
-        */
-       status_t (*pkcs1_encrypt) (rsa_public_key_t *this, chunk_t in, chunk_t *out);
-
-       /**
-        * @brief Verify an EMSA-PKCS1 encoded signature.
-        * 
-        * Processes the supplied signature with the RSAVP1 function,
-        * selects the hash algorithm form the resultign ASN1-OID and
-        * verifies the hash against the supplied data.
-        * 
-        * @param this                          rsa_public_key to use
-        * @param data                          data to sign
-        # @param algorithm                     hash algorithm the signature is based on
-        * @param signature                     signature to verify
-        * @return
-        *                                                      - SUCCESS, if signature ok
-        *                                                      - INVALID_STATE, if key not set
-        *                                                      - NOT_SUPPORTED, if hash algorithm not supported
-        *                                                      - INVALID_ARG, if signature is not a signature
-        *                                                      - FAILED if signature invalid or unable to verify
-        */
-       status_t (*verify_emsa_pkcs1_signature) (const rsa_public_key_t *this,
-                                                                                        hash_algorithm_t algorithm,
-                                                                                        chunk_t data, chunk_t signature);
-       
-       /**
-        * @brief Get the modulus of the key.
-        * 
-        * @param this                          calling object
-        * @return                                      modulus (n) of the key
-        */
-       mpz_t *(*get_modulus) (const rsa_public_key_t *this);
-       
-       /**
-        * @brief Get the size of the modulus in bytes.
-        * 
-        * @param this                          calling object
-        * @return                                      size of the modulus (n) in bytes
-        */
-       size_t (*get_keysize) (const rsa_public_key_t *this);
-
-       /**
-        * @brief Get the DER encoded publicKeyInfo object.
-        * 
-        * @param this                          calling object
-        * @return                                      DER encoded publicKeyInfo object
-        */
-       chunk_t (*get_publicKeyInfo) (const rsa_public_key_t *this);
-
-       /**
-        * @brief Get the keyid formed as the SHA-1 hash of a publicKeyInfo object.
-        * 
-        * @param this                          calling object
-        * @return                                      keyid in the form of a SHA-1 hash
-        */
-       chunk_t (*get_keyid) (const rsa_public_key_t *this);
-
-       /**
-        * @brief Clone the public key.
-        * 
-        * @param this                          public key to clone
-        * @return                                      clone of this
-        */
-       rsa_public_key_t *(*clone) (const rsa_public_key_t *this);
-       
-       /**
-        * @brief Destroys the public key.
-        * 
-        * @param this                          public key to destroy
-        */
-       void (*destroy) (rsa_public_key_t *this);
-};
-
-/**
- * @brief Create a RSA public key from modulus and public exponent.
- *
- * @param n                                    modulus
- * @param e                                    public exponent
- * @return                                     created rsa_public_key_t
- * 
- * @ingroup rsa
- */
-rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e);
-
-/**
- * @brief Load an RSA public key from a chunk.
- * 
- * Load a key from a chunk, encoded in the more frequently
- * used publicKeyInfo object (ASN1 DER encoded).
- * 
- * @param chunk                                chunk containing the DER encoded key
- * @return                                     loaded rsa_public_key_t, or NULL
-  * 
- * @ingroup rsa
- */
-rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Load an RSA public key from a file.
- * 
- * Load a key from a file, which is either in binary
- * format (DER), or in PEM format. 
- * 
- * @param filename                     filename which holds the key
- * @return                                     loaded rsa_public_key_t, or NULL
- * 
- * @ingroup rsa
- */
-rsa_public_key_t *rsa_public_key_create_from_file(char *filename);
-
-#endif /*RSA_PUBLIC_KEY_H_*/
index 747bc5efa8431c73c06f8a1fdf9f8b744e45a62f..377c2b92146efc4108b3bda5095b1cc9da33d70a 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file signer.c
- * 
- * @brief Implementation of generic signer_t constructor.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 "signer.h"
 
-#include <crypto/signers/hmac_signer.h>
-
 ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_HMAC_SHA1_128,
        "UNDEFINED",
        "AUTH_HMAC_SHA1_128");
@@ -40,26 +33,3 @@ ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_SHA2_256_128, AUTH_HMAC_SHA2_512_
        "AUTH_HMAC_SHA2_512_256");
 ENUM_END(integrity_algorithm_names, AUTH_HMAC_SHA2_512_256);
 
-/*
- * Described in header.
- */
-signer_t *signer_create(integrity_algorithm_t integrity_algorithm)
-{
-       switch(integrity_algorithm)
-       {
-               case AUTH_HMAC_SHA1_96:
-                       return (signer_t *)hmac_signer_create(HASH_SHA1, 12);
-               case AUTH_HMAC_SHA1_128:
-                       return (signer_t *)hmac_signer_create(HASH_SHA1, 16);
-               case AUTH_HMAC_MD5_96:
-                       return (signer_t *)hmac_signer_create(HASH_MD5, 12);
-               case AUTH_HMAC_SHA2_256_128:
-                       return (signer_t *)hmac_signer_create(HASH_SHA256, 16);
-               case AUTH_HMAC_SHA2_384_192:
-                       return (signer_t *)hmac_signer_create(HASH_SHA384, 24);
-               case AUTH_HMAC_SHA2_512_256:
-                       return (signer_t *)hmac_signer_create(HASH_SHA512, 32);
-               default:
-                       return NULL;
-       }
-}
index 4218e41462a0cac0d198f6b77e8448080d375366..cfc6652bcaf0e8cbe59d514180e846c97a97458d 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file signer.h
- * 
- * @brief Interface for signer_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 signer signer
+ * @{ @ingroup crypto
  */
 
 #ifndef SIGNER_H_
@@ -30,11 +30,9 @@ typedef struct signer_t signer_t;
 #include <library.h>
 
 /**
- * @brief Integrity algorithm, as in IKEv2 RFC 3.3.2.
+ * Integrity algorithm, as in IKEv2 RFC 3.3.2.
  *
  * Algorithms not specified in IKEv2 are allocated in private use space.
- *
- * @ingroup signers
  */
 enum integrity_algorithm_t {
        AUTH_UNDEFINED = 1024,
@@ -61,93 +59,65 @@ enum integrity_algorithm_t {
 extern enum_name_t *integrity_algorithm_names;
 
 /**
- * @brief Generig interface for a symmetric signature algorithm.
- *
- * @b Constructors:
- *  - signer_create()
- *  - hmac_signer_create()
- *
- * @todo Implement more integrity algorithms
- *
- * @ingroup signers
+ * Generig interface for a symmetric signature algorithm.
  */
 struct signer_t {
        /**
-        * @brief Generate a signature.
+        * Generate a signature.
         *
         * If buffer is NULL, data is processed and prepended to a next call until
         * buffer is a valid pointer.
         * 
-        * @param this                  calling object
-        * @param data                  a chunk containing the data to sign
-        * @param[out] buffer   pointer where the signature will be written
+        * @param data          a chunk containing the data to sign
+        * @param buffer        pointer where the signature will be written
         */
        void (*get_signature) (signer_t *this, chunk_t data, u_int8_t *buffer);
        
        /**
-        * @brief Generate a signature and allocate space for it.
+        * Generate a signature and allocate space for it.
         *
         * If chunk is NULL, data is processed and prepended to a next call until
         * chunk is a valid chunk pointer.
         * 
-        * @param this                  calling object
-        * @param data                  a chunk containing the data to sign
-        * @param[out] chunk    chunk which will hold the allocated signature
+        * @param data          a chunk containing the data to sign
+        * @param chunk         chunk which will hold the allocated signature
         */
        void (*allocate_signature) (signer_t *this, chunk_t data, chunk_t *chunk);
        
        /**
-        * @brief Verify a signature.
+        * Verify a signature.
         * 
-        * @param this                  calling object
-        * @param data                  a chunk containing the data to verify
-        * @param signature             a chunk containing the signature
-        * @return                              TRUE, if signature is valid, FALSE otherwise
+        * @param data          a chunk containing the data to verify
+        * @param signature     a chunk containing the signature
+        * @return                      TRUE, if signature is valid, FALSE otherwise
         */
        bool (*verify_signature) (signer_t *this, chunk_t data, chunk_t signature);
        
        /**
-        * @brief Get the block size of this signature algorithm.
+        * Get the block size of this signature algorithm.
         * 
-        * @param this                  calling object
-        * @return                              block size in bytes
+        * @return                      block size in bytes
         */
        size_t (*get_block_size) (signer_t *this);
        
        /**
-        * @brief Get the key size of the signature algorithm.
+        * Get the key size of the signature algorithm.
         * 
-        * @param this                  calling object
-        * @return                              key size in bytes
+        * @return                      key size in bytes
         */
        size_t (*get_key_size) (signer_t *this);
        
        /**
-        * @brief Set the key for this object.
+        * Set the key for this object.
         * 
-        * @param this                  calling object
-        * @param key                   key to set
+        * @param key           key to set
         */
        void (*set_key) (signer_t *this, chunk_t key);
        
        /**
-        * @brief Destroys a signer_t object.
-        *
-        * @param this                  calling object
+        * Destroys a signer_t object.
         */
        void (*destroy) (signer_t *this);
 };
 
-/**
- * @brief Creates a new signer_t object.
- * 
- * @param integrity_algorithm  Algorithm to use for signing and verifying.
- * @return
- *                                                             - signer_t object
- *                                                             - NULL if signer not supported
- * 
- * @ingroup signers
- */
-signer_t *signer_create(integrity_algorithm_t integrity_algorithm);
-
-#endif /*SIGNER_H_*/
+#endif /*SIGNER_H_ @} */
diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c
deleted file mode 100755 (executable)
index ff490a0..0000000
+++ /dev/null
@@ -1,1562 +0,0 @@
-/**
- * @file x509.c
- * 
- * @brief Implementation of x509_t.
- * 
- */
-
-/*
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2006 Martin Willi
- * Copyright (C) 2000-2008 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.
- *
- * RCSID $Id$
- */
-
-#include <gmp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "x509.h"
-#include "hashers/hasher.h"
-#include <library.h>
-#include <debug.h>
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-#define CERT_WARNING_INTERVAL  30      /* days */
-
-/**
- * Different kinds of generalNames
- */
-typedef enum generalNames_t generalNames_t;
-
-enum generalNames_t {
-       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,
-};
-
-typedef struct private_x509_t private_x509_t;
-
-/**
- * Private data of a x509_t object.
- */
-struct private_x509_t {
-       /**
-        * Public interface for this certificate.
-        */
-       x509_t public;
-       
-       /**
-        * Time when certificate was installed
-        */
-       time_t installed;
-
-       /**
-        * Time until certificate can be trusted
-        */
-       time_t until;
-
-       /**
-        * Certificate status
-        */
-       cert_status_t status;
-
-       /**
-        * Authority flags
-        */
-        u_int authority_flags;
-
-       /**
-        * X.509 Certificate in DER format
-        */
-       chunk_t certificate;
-
-       /**
-        * X.509 certificate body over which signature is computed
-        */
-       chunk_t tbsCertificate;
-
-       /**
-        * Version of the X.509 certificate
-        */
-       u_int version;
-       
-       /**
-        * Serial number of the X.509 certificate
-        */
-       chunk_t serialNumber;
-
-       /**
-        * Signature algorithm
-        */
-       int signatureAlgorithm;
-       
-       /**
-        * ID representing the certificate issuer
-        */
-       identification_t *issuer;
-       
-       /**
-        * link to the info recored of the certificate issuer
-        */
-       ca_info_t *ca_info;
-
-       /**
-        * Start time of certificate validity
-        */
-       time_t notBefore;
-
-       /**
-        * End time of certificate validity
-        */
-       time_t notAfter;
-
-       /**
-        * ID representing the certificate subject
-        */
-       identification_t *subject;
-       
-       /**
-        * List of identification_t's representing subjectAltNames
-        */
-       linked_list_t *subjectAltNames;
-       
-       /**
-        * List of identification_t's representing crlDistributionPoints
-        */
-       linked_list_t *crlDistributionPoints;
-
-       /**
-        * List of identification_t's representing ocspAccessLocations
-        */
-       linked_list_t *ocspAccessLocations;
-
-       /**
-        * Subject public key
-        */
-       chunk_t subjectPublicKey;
-
-       /**
-        * Subject RSA public key, if subjectPublicKeyAlgorithm == RSA
-        */
-       rsa_public_key_t *public_key;
-       
-       /**
-        * Subject Key Identifier
-        */
-       chunk_t subjectKeyID;
-
-       /**
-        * Authority Key Identifier
-        */
-       chunk_t authKeyID;
-
-       /**
-        * Authority Key Serial Number
-        */
-       chunk_t authKeySerialNumber;
-       
-       /**
-        * Indicates if the certificate is self-signed
-        */
-       bool isSelfSigned;
-
-       /**
-        * CA basic constraints flag
-        */
-       bool isCA;
-
-       /**
-        * OCSPSigner extended key usage flag
-        */
-       bool isOcspSigner;
-
-       /**
-        * Signature
-        */
-       chunk_t signature;
-
-};
-
-/**
- * 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,   "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 */
-};
-#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_REGISTERED_ID   16
-#define GN_OBJ_ROOF                            18
-
-/**
- * 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 */
-};
-#define ON_OBJ_ID_TYPE         0
-#define ON_OBJ_VALUE           1
-#define ON_OBJ_ROOF                    2
-/**
- * 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 */
-};
-#define BASIC_CONSTRAINTS_CA   1
-#define BASIC_CONSTRAINTS_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 */
-};
-#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 */
-};
-#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
- */
-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 */
-};
-
-#define EXT_KEY_USAGE_PURPOSE_ID       1
-#define EXT_KEY_USAGE_ROOF                     3
-
-/**
- * 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 */
-};
-#define GENERAL_NAMES_GN       1
-#define GENERAL_NAMES_ROOF     3
-
-
-/**
- * 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,       "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 */
-};
-#define CRL_DIST_POINTS_FULLNAME        3
-#define CRL_DIST_POINTS_ROOF           13
-
-/**
- * ASN.1 definition of an X.509v3 x509
- */
-static const asn1Object_t certObjects[] = {
-       { 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_NONE                       }, /* 11 */
-       { 3,       "algorithm",                 ASN1_EOC,                       ASN1_RAW                        }, /* 12 */
-       { 3,       "subjectPublicKey",  ASN1_BIT_STRING,        ASN1_NONE                       }, /* 13 */
-       { 4,         "RSAPublicKey",    ASN1_SEQUENCE,          ASN1_RAW                        }, /* 14 */
-       { 2,     "issuerUniqueID",              ASN1_CONTEXT_C_1,       ASN1_OPT                        }, /* 15 */
-       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /* 16 */
-       { 2,     "subjectUniqueID",             ASN1_CONTEXT_C_2,       ASN1_OPT                        }, /* 17 */
-       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /* 18 */
-       { 2,     "optional extensions", ASN1_CONTEXT_C_3,       ASN1_OPT                        }, /* 19 */
-       { 3,       "extensions",                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 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_EXTN_ID                                               22
-#define X509_OBJ_CRITICAL                                              23
-#define X509_OBJ_EXTN_VALUE                                            24
-#define X509_OBJ_ALGORITHM                                             27
-#define X509_OBJ_SIGNATURE                                             28
-#define X509_OBJ_ROOF                                                  29
-
-
-static u_char ASN1_subjectAltName_oid_str[] = {
-       0x06, 0x03, 0x55, 0x1D, 0x11
-};
-
-static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_subjectAltName_oid_str);
-
-
-/**
- * compare two X.509 x509s by comparing their signatures
- */
-static bool equals(const private_x509_t *this, const private_x509_t *other)
-{
-       return chunk_equals(this->signature, other->signature);
-}
-
-/**
- * extracts the basicConstraints extension
- */
-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, FALSE);
-
-       while (objectID < BASIC_CONSTRAINTS_ROOF) {
-
-               if (!extract_object(basicConstraintsObjects, &objectID, &object,&level, &ctx))
-               {
-                       break;
-               }
-               if (objectID == BASIC_CONSTRAINTS_CA)
-               {
-                       isCA = object.len && *object.ptr;
-                       DBG2("  %s", isCA ? "TRUE" : "FALSE");
-               }
-               objectID++;
-       }
-       return isCA;
-}
-
-/**
- * extracts an otherName
- */
-static bool parse_otherName(chunk_t blob, int level0)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-       int oid = OID_UNKNOWN;
-
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
-       while (objectID < ON_OBJ_ROOF)
-       {
-               if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
-                       return FALSE;
-
-               switch (objectID)
-               {
-                       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"))
-                                               return FALSE;
-                               }
-                               break;
-                       default:
-                               break;
-               }
-               objectID++;
-       }
-       return TRUE;
-}
-
-/**
- * extracts a generalName
- */
-static identification_t *parse_generalName(chunk_t blob, int level0)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       int objectID = 0;
-       u_int level;
-
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
-       while (objectID < GN_OBJ_ROOF)
-       {
-               id_type_t id_type = ID_ANY;
-       
-               if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
-                       return NULL;
-
-               switch (objectID)
-               {
-                       case GN_OBJ_RFC822_NAME:
-                               id_type = ID_RFC822_ADDR;
-                               break;
-                       case GN_OBJ_DNS_NAME:
-                               id_type = ID_FQDN;
-                               break;
-                       case GN_OBJ_URI:
-                               id_type = ID_DER_ASN1_GN_URI;
-                               break;
-                       case GN_OBJ_DIRECTORY_NAME:
-                               id_type = ID_DER_ASN1_DN;
-                       break;
-                       case GN_OBJ_IP_ADDRESS:
-                               id_type = (object.len == 4)? ID_IPV4_ADDR : ID_IPV6_ADDR;
-                               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 (id_type != ID_ANY)
-               {
-                       identification_t *gn = identification_create_from_encoding(id_type, object);
-                       DBG2("  '%D'", gn);
-                       return gn;
-        }
-               objectID++;
-    }
-    return NULL;
-}
-
-
-/*
- * Defined in header.
- */
-void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-
-       asn1_init(&ctx, blob, level0, implicit, FALSE);
-
-       while (objectID < GENERAL_NAMES_ROOF)
-       {
-               if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
-                       return;
-               
-               if (objectID == GENERAL_NAMES_GN)
-               {
-                       identification_t *gn = parse_generalName(object, level+1);
-
-                       if (gn != NULL)
-                               list->insert_last(list, (void *)gn);
-               }
-               objectID++;
-       }
-       return;
-}
-
-/**
- * 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, FALSE);
-       
-       extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx);
-       return object;
-}
-
-/*
- * Defined in header.
- */
-void x509_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;
-       
-       *authKeyID = chunk_empty;
-       *authKeySerialNumber = chunk_empty;
-
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
-       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:
-                       {
-                               /* TODO: parse_generalNames(object, level+1, TRUE); */
-                               break;
-                       }
-                       case AUTH_KEY_ID_CERT_SERIAL:
-                               *authKeySerialNumber = object;
-                               break;
-                       default:
-                               break;
-               }
-               objectID++;
-       }
-}
-
-/**
- * extracts an authorityInfoAcess location
- */
-static void parse_authorityInfoAccess(chunk_t blob, int level0, linked_list_t *list)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-       int accessMethod = OID_UNKNOWN;
-       
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-       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)
-                               {
-                                       case OID_OCSP:
-                                       case OID_CA_ISSUERS:
-                                               {
-                                                       identification_t *accessLocation;
-
-                                                       accessLocation = parse_generalName(object, level+1);
-                                                       if (accessLocation == NULL)
-                                                       {
-                                                               /* parsing went wrong - abort */
-                                                               return;
-                                                       }
-                                                       DBG2("  '%D'", accessLocation);
-                                                       if (accessMethod == OID_OCSP)
-                                                       {
-                                                               list->insert_last(list, (void *)accessLocation);
-                                                       }
-                                                       else
-                                                       {
-                                                               /* caIsssuer accessLocation is not used yet */
-                                                               accessLocation->destroy(accessLocation);
-                                                       }
-                                               }
-                                               break;
-                                       default:
-                                               /* unkown accessMethod, ignoring */
-                                               break;
-                               }
-                               break;
-                       }
-                       default:
-                               break;
-               }
-               objectID++;
-       }
-}
-
-/**
- * extracts extendedKeyUsage OIDs
- */
-static bool parse_extendedKeyUsage(chunk_t blob, int level0)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-       
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-       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;
-}
-
-/**
- * extracts one or several crlDistributionPoints and puts them into
- * a chained list
- */
-static void parse_crlDistributionPoints(chunk_t blob, int level0, linked_list_t *list)
-{
-       asn1_ctx_t ctx;
-       chunk_t object;
-       u_int level;
-       int objectID = 0;
-       
-       asn1_init(&ctx, blob, level0, FALSE, FALSE);
-       while (objectID < CRL_DIST_POINTS_ROOF)
-       {
-               if (!extract_object(crlDistributionPointsObjects, &objectID, &object, &level, &ctx))
-               {
-                       return;
-               }
-               if (objectID == CRL_DIST_POINTS_FULLNAME)
-               {
-                       /* append extracted generalNames to existing chained list */
-                       x509_parse_generalNames(object, level+1, TRUE, list);
-
-               }
-               objectID++;
-       }
-}
-
-
-/**
- * Parses an X.509v3 certificate
- */
-static bool parse_certificate(chunk_t blob, u_int level0, private_x509_t *this)
-{
-       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, FALSE);
-       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:
-                               this->certificate = object;
-                               break;
-                       case X509_OBJ_TBS_CERTIFICATE:
-                               this->tbsCertificate = object;
-                               break;
-                       case X509_OBJ_VERSION:
-                               this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
-                               DBG2("  v%d", this->version);
-                               break;
-                       case X509_OBJ_SERIAL_NUMBER:
-                               this->serialNumber = object;
-                               break;
-                       case X509_OBJ_SIG_ALG:
-                               this->signatureAlgorithm = parse_algorithmIdentifier(object, level, NULL);
-                               break;
-                       case X509_OBJ_ISSUER:
-                               this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
-                               DBG2("  '%D'", this->issuer);
-                               break;
-                       case X509_OBJ_NOT_BEFORE:
-                               this->notBefore = parse_time(object, level);
-                               break;
-                       case X509_OBJ_NOT_AFTER:
-                               this->notAfter = parse_time(object, level);
-                               break;
-                       case X509_OBJ_SUBJECT:
-                               this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
-                               DBG2("  '%D'", this->subject);
-                               break;
-                       case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
-                               if (parse_algorithmIdentifier(object, level, NULL) != OID_RSA_ENCRYPTION)
-                               {
-                                       DBG1("  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
-                               {
-                                       DBG1("  invalid RSA public key format");
-                                       return FALSE;
-                               }
-                               break;
-                       case X509_OBJ_RSA_PUBLIC_KEY:
-                               this->subjectPublicKey = object;
-                               break;
-                       case X509_OBJ_EXTN_ID:
-                               extn_oid = known_oid(object);
-                               break;
-                       case X509_OBJ_CRITICAL:
-                               critical = object.len && *object.ptr;
-                               DBG2("  %s", critical ? "TRUE" : "FALSE");
-                               break;
-                       case X509_OBJ_EXTN_VALUE:
-                       {
-                               switch (extn_oid)
-                               {
-                                       case OID_SUBJECT_KEY_ID:
-                                               this->subjectKeyID = chunk_clone(parse_keyIdentifier(object, level, FALSE));
-                                               break;
-                                       case OID_SUBJECT_ALT_NAME:
-                                               x509_parse_generalNames(object, level, FALSE, this->subjectAltNames);
-                                               break;
-                                       case OID_BASIC_CONSTRAINTS:
-                                               this->isCA = parse_basicConstraints(object, level);
-                                               break;
-                                       case OID_CRL_DISTRIBUTION_POINTS:
-                                               parse_crlDistributionPoints(object, level, this->crlDistributionPoints);
-                                               break;
-                                       case OID_AUTHORITY_KEY_ID:
-                                               x509_parse_authorityKeyIdentifier(object, level,
-                                                        &this->authKeyID, &this->authKeySerialNumber);
-                                               break;
-                                       case OID_AUTHORITY_INFO_ACCESS:
-                                               parse_authorityInfoAccess(object, level, this->ocspAccessLocations);
-                                               break;
-                                       case OID_EXTENDED_KEY_USAGE:
-                                               this->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;
-                                       default:
-                                               break;
-                               }
-                               break;
-                       }
-                       case X509_OBJ_ALGORITHM:
-                               {
-                                       int alg = parse_algorithmIdentifier(object, level, NULL);
-
-                                       if (alg != this->signatureAlgorithm)
-                                       {
-                                               DBG1("  signature algorithms do not agree");
-                                               return FALSE;
-                                       }
-                               }
-                               break;
-                       case X509_OBJ_SIGNATURE:
-                               this->signature = object;
-                               break;
-                       default:
-                               break;
-               }
-               objectID++;
-       }
-
-       /* generate the subjectKeyID if it is missing in the certificate */
-       if (this->subjectKeyID.ptr == NULL)
-       {
-               hasher_t *hasher = hasher_create(HASH_SHA1);
-
-               hasher->allocate_hash(hasher, this->subjectPublicKey, &this->subjectKeyID);
-               hasher->destroy(hasher);
-       }
-
-       this->installed = time(NULL);
-       return TRUE;
-}
-
-/**
- * Implements x509_t.is_valid
- */
-static err_t is_valid(const private_x509_t *this, time_t *until)
-{
-       time_t current_time = time(NULL);
-       
-       DBG2("  not before  : %T", &this->notBefore);
-       DBG2("  current time: %T", &current_time);
-       DBG2("  not after   : %T", &this->notAfter);
-
-       if (until != NULL &&
-               (*until == UNDEFINED_TIME || this->notAfter < *until))
-       {
-               *until = this->notAfter;
-       }
-       if (current_time < this->notBefore)
-       {
-               return "is not valid yet";
-       }
-       if (current_time > this->notAfter)
-       {
-               return "has expired";
-       }
-       DBG2("  certificate is valid");
-       return NULL;
-}
-
-/**
- * Implements x509_t.is_ca
- */
-static bool is_ca(const private_x509_t *this)
-{
-       return this->isCA;
-}
-
-/**
- * Implements x509_t.is_ocsp_signer
- */
-static bool is_ocsp_signer(const private_x509_t *this)
-{
-       return this->isOcspSigner;
-}
-
-/**
- * Implements x509_t.is_self_signed
- */
-static bool is_self_signed(const private_x509_t *this)
-{
-       return this->isSelfSigned;
-}
-
-/**
- * Implements x509_t.equals_subjectAltName
- */
-static bool equals_subjectAltName(const private_x509_t *this, identification_t *id)
-{
-       bool found = FALSE;
-       identification_t *subjectAltName;
-       iterator_t *iterator;
-       
-       iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE);
-       while (iterator->iterate(iterator, (void**)&subjectAltName))
-       {
-               if (id->equals(id, subjectAltName))
-               {
-                       found = TRUE;
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       return found;
-}
-
-/**
- * Implements x509_t.is_issuer
- */
-static bool is_issuer(const private_x509_t *this, const private_x509_t *issuer)
-{
-       return (this->authKeyID.ptr)
-                       ? chunk_equals(this->authKeyID, issuer->subjectKeyID)
-                       : (this->issuer->equals(this->issuer, issuer->subject)
-                          && chunk_equals_or_null(this->authKeySerialNumber, issuer->serialNumber));
-}
-
-/**
- * Implements x509_t.get_certificate
- */
-static chunk_t get_certificate(const private_x509_t *this)
-{
-       return this->certificate;
-}
-
-/**
- * Implements x509_t.get_public_key
- */
-static rsa_public_key_t *get_public_key(const private_x509_t *this)
-{
-       return this->public_key;
-}
-
-/**
- * Implements x509_t.get_serialNumber
- */
-static chunk_t get_serialNumber(const private_x509_t *this)
-{
-       return this->serialNumber;
-}
-
-/**
- * Implements x509_t.get_subjectKeyID
- */
-static chunk_t get_subjectKeyID(const private_x509_t *this)
-{
-       return this->subjectKeyID;
-}
-
-/**
- * Implements x509_t.get_keyid
- */
-static chunk_t get_keyid(const private_x509_t *this)
-{
-       return this->public_key->get_keyid(this->public_key);
-}
-
-/**
- * Implements x509_t.get_issuer
- */
-static identification_t *get_issuer(const private_x509_t *this)
-{
-       return this->issuer;
-}
-
-/**
- * Implements x509_t.get_subject
- */
-static identification_t *get_subject(const private_x509_t *this)
-{
-       return this->subject;
-}
-
-/**
- * Implements x509_t.set_ca_info
- */
-static void set_ca_info(private_x509_t *this, ca_info_t *ca_info)
-{
-       this->ca_info = ca_info;
-}
-
-/**
- * Implements x509_t.get_ca_info
- */
-static ca_info_t *get_ca_info(const private_x509_t *this)
-{
-       return this->ca_info;
-}
-
-/**
- * Implements x509_t.set_until
- */
-static void set_until(private_x509_t *this, time_t until)
-{
-       this->until = until;
-}
-
-/**
- * Implements x509_t.get_until
- */
-static time_t get_until(const private_x509_t *this)
-{
-       return this->until;
-}
-
-/**
- * Implements x509_t.set_status
- */
-static void set_status(private_x509_t *this, cert_status_t status)
-{
-       this->status = status;
-}
-
-/**
- * Implements x509_t.get_status
- */
-static cert_status_t get_status(const private_x509_t *this)
-{
-       return this->status;
-}
-
-/**
- * Implements x509_t.add_authority_flags
- */
-static void add_authority_flags(private_x509_t *this, u_int flags)
-{
-       this->authority_flags |= flags;
-}
-
-/**
- * Implements x509_t.add_authority_flags
- */
-static u_int get_authority_flags(private_x509_t *this)
-{
-       return this->authority_flags;
-}
-
-/**
- * Implements x509_t.has_authority_flag
- */
-static bool has_authority_flag(private_x509_t *this, u_int flags)
-{
-       return (this->authority_flags & flags) != AUTH_NONE;
-}
-
-/**
- * Implements x509_t.create_crluri_iterator
- */
-static iterator_t *create_crluri_iterator(const private_x509_t *this)
-{
-       return this->crlDistributionPoints->create_iterator(this->crlDistributionPoints, TRUE);
-}
-
-/**
- * Implements x509_t.create_crluri_iterator
- */
-static iterator_t *create_ocspuri_iterator(const private_x509_t *this)
-{
-       return this->ocspAccessLocations->create_iterator(this->ocspAccessLocations, TRUE);
-}
-
-/**
- * Implements x509_t.verify
- */
-static bool verify(const private_x509_t *this, const rsa_public_key_t *signer)
-{
-       hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->signatureAlgorithm);
-
-       if (algorithm == HASH_UNKNOWN)
-       {
-               DBG1("  unknown signature algorithm");
-               return FALSE;
-       }
-       return signer->verify_emsa_pkcs1_signature(signer, algorithm, this->tbsCertificate, this->signature) == SUCCESS;
-}
-       
-/**
- * Implementation of x509_t.list.
- */
-static void list(private_x509_t *this, FILE *out, bool utc)
-{
-       iterator_t *iterator;
-       time_t now = time(NULL);
-
-       fprintf(out, "%#T\n", &this->installed, utc);
-
-       if (this->subjectAltNames->get_count(this->subjectAltNames))
-       {
-               identification_t *subjectAltName;
-               bool first = TRUE;
-
-               fprintf(out, "    altNames:  ");
-               iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE);
-               while (iterator->iterate(iterator, (void**)&subjectAltName))
-               {
-                       if (first)
-                       {
-                               first = FALSE;
-                       }
-                       else
-                       {
-                               fprintf(out, ", ");
-                       }
-                       fprintf(out, "'%D'", subjectAltName);
-               }
-               iterator->destroy(iterator);
-               fprintf(out, "\n");
-       }
-       fprintf(out, "    subject:   '%D'\n", this->subject);
-       fprintf(out, "    issuer:    '%D'\n", this->issuer);
-       fprintf(out, "    serial:     %#B\n", &this->serialNumber);
-       fprintf(out, "    validity:   not before %#T, ", &this->notBefore, utc);
-       if (now < this->notBefore)
-       {
-               fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
-       }
-       else
-       {
-               fprintf(out, "ok\n");
-       }
-       
-       fprintf(out, "                not after  %#T, ", &this->notAfter, utc);
-       if (now > this->notAfter)
-       {
-               fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
-       }
-       else
-       {
-               fprintf(out, "ok");
-               if (now > this->notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
-               {
-                       fprintf(out, " (expires in %#V)", &now, &this->notAfter);
-               }
-               fprintf(out, " \n");
-       }
-       
-       {
-               chunk_t keyid = this->public_key->get_keyid(this->public_key);
-               fprintf(out, "    keyid:      %#B\n", &keyid);
-       }
-
-       if (this->subjectKeyID.ptr)
-       {
-               fprintf(out, "    subjkey:    %#B\n", &this->subjectKeyID);
-       }
-       if (this->authKeyID.ptr)
-       {
-               fprintf(out, "    authkey:    %#B\n", &this->authKeyID);
-       }
-       if (this->authKeySerialNumber.ptr)
-       {
-               fprintf(out, "    aserial:    %#B\n", &this->authKeySerialNumber);
-       }
-       
-       fprintf(out, "    pubkey:     RSA %d bits", BITS_PER_BYTE *
-                       this->public_key->get_keysize(this->public_key));
-       fprintf(out, ", status %N",
-                  cert_status_names, this->status);
-       
-       switch (this->status)
-       {
-               case CERT_GOOD:
-                       fprintf(out, " until %#T", &this->until, utc);
-                       break;
-               case CERT_REVOKED:
-                       fprintf(out, " on %#T", &this->until, utc);
-                       break;
-               case CERT_UNKNOWN:
-               case CERT_UNDEFINED:
-               case CERT_UNTRUSTED:
-               default:
-                       break;
-       }
-}
-
-/**
- * Implements x509_t.add_subjectAltNames.
- */
-static void add_subjectAltNames(private_x509_t *this, linked_list_t *subjectAltNames)
-{
-       iterator_t *iterator = subjectAltNames->create_iterator(subjectAltNames, TRUE);
-       identification_t *name = NULL;
-
-       while (iterator->iterate(iterator, (void**)&name))
-       {
-               name = name->clone(name);
-               this->subjectAltNames->insert_last(this->subjectAltNames, (void*)name);
-       }
-       iterator->destroy(iterator);
-}
-
-/*
- * Defined in header.
- */
-chunk_t x509_build_generalNames(linked_list_t *list)
-{
-       linked_list_t *generalNames = linked_list_create();
-       iterator_t *iterator = list->create_iterator(list, TRUE);
-       identification_t *name;
-       chunk_t names = chunk_empty;
-       size_t len = 0;
-
-       while (iterator->iterate(iterator, (void**)&name))
-       {
-               asn1_t asn1_type = ASN1_EOC;
-               chunk_t *generalName;
-
-               switch (name->get_type(name))
-               {
-                       case ID_RFC822_ADDR:
-                               asn1_type = ASN1_CONTEXT_S_1;
-                               break;
-                       case ID_FQDN:
-                               asn1_type = ASN1_CONTEXT_S_2;
-                               break;
-                       case ID_DER_ASN1_DN:
-                               asn1_type = ASN1_CONTEXT_C_4;
-                       break;
-                       case ID_DER_ASN1_GN_URI:
-                               asn1_type = ASN1_CONTEXT_S_6;
-                               break;
-                       case ID_IPV4_ADDR:
-                       case ID_IPV6_ADDR:
-                               asn1_type = ASN1_CONTEXT_S_7;
-                               break;
-                       default:
-                               continue;
-               }
-
-               generalName = malloc_thing(chunk_t);
-               *generalName = asn1_simple_object(asn1_type, name->get_encoding(name));
-               len += generalName->len;
-               generalNames->insert_last(generalNames, (void*)generalName);
-       }
-       iterator->destroy(iterator);
-
-       if (len > 0)
-       {
-               iterator_t *iterator = generalNames->create_iterator(generalNames, TRUE);
-               chunk_t *generalName;
-               u_char *pos = build_asn1_object(&names, ASN1_SEQUENCE, len);
-
-               while (iterator->iterate(iterator, (void**)&generalName))
-               {
-                       memcpy(pos, generalName->ptr, generalName->len);
-                       pos += generalName->len;
-                       free(generalName->ptr);
-                       free(generalName);
-               }
-               iterator->destroy(iterator);
-       }
-       generalNames->destroy(generalNames);
-       return names;
-}
-
-/*
- * Defined in header.
- */
-chunk_t x509_build_subjectAltNames(linked_list_t *list)
-{
-       chunk_t generalNames = x509_build_generalNames(list);
-
-       if (generalNames.len)
-       {
-               return asn1_wrap(ASN1_SEQUENCE, "cm",
-                                       ASN1_subjectAltName_oid,
-                                       asn1_wrap(ASN1_OCTET_STRING, "m", generalNames)
-                               );
-       }
-       else
-       {
-               return chunk_empty;
-       }
-}
-
-/**
- * Build a to-be-signed X.509 certificate body
- */
-static chunk_t x509_build_tbs(private_x509_t *this)
-{
-    /* version is always X.509v3 */
-    chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2);
-
-    chunk_t extensions = chunk_empty;
-
-    if (this->subjectAltNames->get_count(this->subjectAltNames))
-    {
-               extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
-                       asn1_wrap(ASN1_SEQUENCE, "m",
-                       x509_build_subjectAltNames(this->subjectAltNames)));
-    }
-
-    return asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
-                       version,
-                       asn1_simple_object(ASN1_INTEGER, this->serialNumber),
-                       asn1_algorithmIdentifier(this->signatureAlgorithm),
-                       this->issuer->get_encoding(this->issuer),
-                       asn1_wrap(ASN1_SEQUENCE, "mm",
-                               timetoasn1(&this->notBefore, ASN1_UTCTIME),
-                               timetoasn1(&this->notAfter,  ASN1_UTCTIME)
-                       ),
-                       this->subject->get_encoding(this->subject),
-                       this->public_key->get_publicKeyInfo(this->public_key),
-                       extensions
-          );
-}
-
-/**
- * Implementation of x509_t.build_encoding.
- */
-static void build_encoding(private_x509_t *this, hash_algorithm_t alg,
-                                                  rsa_private_key_t *private_key)
-{
-       chunk_t signature;
-
-       this->signatureAlgorithm = hasher_signature_algorithm_to_oid(alg);
-       this->tbsCertificate = x509_build_tbs(this);
-       private_key->build_emsa_pkcs1_signature(private_key, alg,
-                                               this->tbsCertificate, &signature);
-       this->signature = asn1_bitstring("m", signature);
-       this->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm",
-                               this->tbsCertificate,
-                               asn1_algorithmIdentifier(this->signatureAlgorithm),
-                               this->signature);
-
-}
-
-/**
- * Implements x509_t.destroy
- */
-static void destroy(private_x509_t *this)
-{
-       this->subjectAltNames->destroy_offset(this->subjectAltNames,
-                                                               offsetof(identification_t, destroy));
-       this->crlDistributionPoints->destroy_offset(this->crlDistributionPoints,
-                                                               offsetof(identification_t, destroy));
-       this->ocspAccessLocations->destroy_offset(this->ocspAccessLocations,
-                                                               offsetof(identification_t, destroy));
-       DESTROY_IF(this->issuer);
-       DESTROY_IF(this->subject);
-       DESTROY_IF(this->public_key);
-       free(this->subjectKeyID.ptr);
-       free(this->certificate.ptr);
-       free(this);
-}
-
-/**
- * Internal generic constructor
- */
-static private_x509_t *x509_create_empty(void)
-{
-       private_x509_t *this = malloc_thing(private_x509_t);
-       
-       /* initialize */
-       this->subjectPublicKey = chunk_empty;
-       this->public_key = NULL;
-       this->subject = NULL;
-       this->issuer = NULL;
-       this->ca_info = NULL;
-       this->subjectAltNames = linked_list_create();
-       this->crlDistributionPoints = linked_list_create();
-       this->ocspAccessLocations = linked_list_create();
-       this->subjectKeyID = chunk_empty;
-       this->authKeyID = chunk_empty;
-       this->authKeySerialNumber = chunk_empty;
-       this->authority_flags = AUTH_NONE;
-       this->isCA = FALSE;
-       this->isOcspSigner = FALSE;
-       
-       /* public functions */
-       this->public.equals = (bool (*) (const x509_t*,const x509_t*))equals;
-       this->public.equals_subjectAltName = (bool (*) (const x509_t*,identification_t*))equals_subjectAltName;
-       this->public.is_issuer = (bool (*) (const x509_t*,const x509_t*))is_issuer;
-       this->public.is_valid = (err_t (*) (const x509_t*,time_t*))is_valid;
-       this->public.is_ca = (bool (*) (const x509_t*))is_ca;
-       this->public.is_self_signed = (bool (*) (const x509_t*))is_self_signed;
-       this->public.is_ocsp_signer = (bool (*) (const x509_t*))is_ocsp_signer;
-       this->public.get_certificate = (chunk_t (*) (const x509_t*))get_certificate;
-       this->public.get_public_key = (rsa_public_key_t* (*) (const x509_t*))get_public_key;
-       this->public.get_serialNumber = (chunk_t (*) (const x509_t*))get_serialNumber;
-       this->public.get_subjectKeyID = (chunk_t (*) (const x509_t*))get_subjectKeyID;
-       this->public.get_keyid = (chunk_t (*) (const x509_t*))get_keyid;
-       this->public.get_issuer = (identification_t* (*) (const x509_t*))get_issuer;
-       this->public.get_subject = (identification_t* (*) (const x509_t*))get_subject;
-       this->public.set_ca_info = (void (*) (x509_t*,ca_info_t*))set_ca_info;
-       this->public.get_ca_info = (ca_info_t* (*) (const x509_t*))get_ca_info;
-       this->public.set_until = (void (*) (x509_t*,time_t))set_until;
-       this->public.get_until = (time_t (*) (const x509_t*))get_until;
-       this->public.set_status = (void (*) (x509_t*,cert_status_t))set_status;
-       this->public.get_status = (cert_status_t (*) (const x509_t*))get_status;
-       this->public.add_authority_flags = (void (*) (x509_t*,u_int))add_authority_flags;
-       this->public.get_authority_flags = (u_int (*) (x509_t*))get_authority_flags;
-       this->public.has_authority_flag = (bool (*) (x509_t*,u_int))has_authority_flag;
-       this->public.create_crluri_iterator = (iterator_t* (*) (const x509_t*))create_crluri_iterator;
-       this->public.create_ocspuri_iterator = (iterator_t* (*) (const x509_t*))create_ocspuri_iterator;
-       this->public.verify = (bool (*) (const x509_t*,const rsa_public_key_t*))verify;
-       this->public.list = (void (*) (x509_t*, FILE *out, bool utc))list;
-       this->public.add_subjectAltNames = (void (*) (x509_t*,linked_list_t*))add_subjectAltNames;
-       this->public.build_encoding = (void (*) (x509_t*,hash_algorithm_t,rsa_private_key_t*))build_encoding;
-       this->public.destroy = (void (*) (x509_t*))destroy;
-       
-       return this;
-}
-
-/*
- * Described in header.
- */
-x509_t *x509_create(chunk_t serialNumber, identification_t *issuer,
-                                       time_t notBefore, time_t notAfter,
-                                       identification_t *subject,
-                                       rsa_public_key_t *public_key)
-{
-       private_x509_t *this = x509_create_empty();
-
-       this->serialNumber = serialNumber;
-       this->issuer = issuer->clone(issuer);
-       this->notBefore = notBefore;
-       this->notAfter = notAfter;
-       this->subject = subject->clone(subject);
-       this->public_key = public_key->clone(public_key);
-
-       return &this->public;
-}
-
-/*
- * Described in header.
- */
-x509_t *x509_create_from_chunk(chunk_t chunk, u_int level)
-{
-       private_x509_t *this = x509_create_empty();
-
-       if (!parse_certificate(chunk, level, this))
-       {
-               destroy(this);
-               return NULL;
-       }
-
-       /* extract public key from certificate */
-       this->public_key = rsa_public_key_create_from_chunk(this->subjectPublicKey);
-       if (this->public_key == NULL)
-       {
-               destroy(this);
-               return NULL;
-       }
-
-       /* set trusted lifetime of public key to notAfter */
-       this->until = this->notAfter;
-
-       /* check if the certificate is self-signed */
-       this->isSelfSigned = FALSE;
-       if (this->subject->equals(this->subject, this->issuer))
-       {
-               hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->signatureAlgorithm);
-
-               if (algorithm == HASH_UNKNOWN)
-               {
-                       destroy(this);
-                       return NULL;
-               }
-               this->isSelfSigned = this->public_key->verify_emsa_pkcs1_signature(this->public_key,
-                                                        algorithm, this->tbsCertificate, this->signature) == SUCCESS;
-       }
-       if (this->isSelfSigned)
-       {
-               DBG2("  certificate is self-signed");
-               this->status = CERT_GOOD;
-       }
-       else
-       {
-               this->status = CERT_UNDEFINED;
-       }
-
-       return &this->public;
-}
-
-/*
- * Described in header.
- */
-x509_t *x509_create_from_file(const char *filename, const char *label)
-{
-       bool pgp = FALSE;
-       chunk_t chunk = chunk_empty;
-       char cert_label[BUF_LEN];
-
-       snprintf(cert_label, BUF_LEN, "%s certificate", label);
-
-       if (!pem_asn1_load_file(filename, NULL, cert_label, &chunk, &pgp))
-       {
-               return NULL;
-       }
-       return x509_create_from_chunk(chunk, 0);
-}
diff --git a/src/libstrongswan/crypto/x509.h b/src/libstrongswan/crypto/x509.h
deleted file mode 100755 (executable)
index 4c49c8e..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-/**
- * @file x509.h
- * 
- * @brief Interface of x509_t.
- * 
- */
-
-/*
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2006 Martin Willi
- * Copyright (C) 2000-2008 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.
- *
- * RCSID $Id$
- */
-
-#ifndef X509_H_
-#define X509_H_
-
-typedef struct x509_t x509_t;
-
-#include <library.h>
-#include <crypto/rsa/rsa_private_key.h>
-#include <crypto/hashers/hasher.h>
-#include <crypto/certinfo.h>
-#include <crypto/ca.h>
-#include <utils/identification.h>
-#include <utils/iterator.h>
-#include <utils/linked_list.h>
-
-/* 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 */
-
-/**
- * @brief X.509 certificate.
- * 
- * @b Constructors:
- *  - x509_create()
- *  - x509_create_from_chunk()
- *  - x509_create_from_file()
- *
- * @ingroup crypto
- */
-struct x509_t {
-
-       /**
-        * @brief Set trusted public key life.
-        * 
-        * @param this                          calling object
-        * @param until                         time until public key is trusted
-        */
-       void (*set_until) (x509_t *this, time_t until);
-
-       /**
-        * @brief Get trusted public key life.
-        * 
-        * @param this                          calling object
-        * @return                                      time until public key is trusted
-        */
-       time_t (*get_until) (const x509_t *this);
-
-       /**
-        * @brief Set the certificate status
-        * 
-        * @param this                          calling object
-        * @param status                        certificate status
-        */
-       void (*set_status) (x509_t *this, cert_status_t status);
-
-       /**
-        * @brief Get the certificate status
-        * 
-        * @param this                          calling object
-        * @return                                      certificate status
-        */
-       cert_status_t (*get_status) (const x509_t *this);
-
-       /**
-        * @brief Add authority flags
-        * 
-        * @param this                          calling object
-        * @param flag                          flags to be added
-        */
-       void (*add_authority_flags) (x509_t *this, u_int flags);
-
-       /**
-        * @brief Get authority flags
-        * 
-        * @param this                          calling object
-        * @return                                      authority flags
-        */
-       u_int (*get_authority_flags) (x509_t *this);
-
-       /**
-        * @brief Check a specific authority flag
-        * 
-        * @param this                          calling object
-        * @param flag                          flag to be checked
-        * @return                                      TRUE if flag is present
-        */
-       bool (*has_authority_flag) (x509_t *this, u_int flag);
-
-       /**
-        * @brief Get the DER-encoded X.509 certificate body
-        * 
-        * @param this                          calling object
-        * @return                                      DER-encoded X.509 certificate
-        */
-       chunk_t (*get_certificate) (const x509_t *this);
-
-       /**
-        * @brief Get the RSA public key from the certificate.
-        * 
-        * @param this                          calling object
-        * @return                                      public_key
-        */
-       rsa_public_key_t *(*get_public_key) (const x509_t *this);
-
-       /**
-        * @brief Get serial number from the certificate.
-        * 
-        * @param this                          calling object
-        * @return                                      serialNumber
-        */
-       chunk_t (*get_serialNumber) (const x509_t *this);
-               
-       /**
-        * @brief Get subjectKeyID from the certificate.
-        * 
-        * @param this                          calling object
-        * @return                                      subjectKeyID
-        */
-       chunk_t (*get_subjectKeyID) (const x509_t *this);
-
-       /**
-        * @brief Get keyid from the certificate's public key.
-        * 
-        * @param this                          calling object
-        * @return                                      keyid
-        */
-       chunk_t (*get_keyid) (const x509_t *this);
-
-       /**
-        * @brief Get the issuerDistinguishedName
-        * 
-        * The resulting ID is always a identification_t
-        * of type ID_DER_ASN1_DN.
-        * 
-        * @param this                          calling object
-        * @return                                      issuers ID
-        */
-       identification_t *(*get_issuer) (const x509_t *this);
-
-       /**
-        * @brief Get the subjectDistinguishedName.
-        * 
-        * The resulting ID is always a identification_t
-        * of type ID_DER_ASN1_DN. 
-        * 
-        * @param this                          calling object
-        * @return                                      subjects ID
-        */
-       identification_t *(*get_subject) (const x509_t *this);
-
-       /**
-        * @brief Set a link  ca info
-        * 
-        * @param this                          calling object
-        * @param ca_info                       link to the info record of the issuing ca
-        */
-       void (*set_ca_info) (x509_t *this, ca_info_t *ca_info);
-
-       /**
-        * @brief Get the .
-        * 
-        * The resulting ID is always a identification_t
-        * of type ID_DER_ASN1_DN. 
-        * 
-        * @param this                          calling object
-        * @return                                      link to the info record of the issuing ca
-        *                                                      or NULL if it does not [yet] exist
-        */
-       ca_info_t *(*get_ca_info) (const x509_t *this);
-
-       /**
-        * @brief Create an iterator for the crlDistributionPoints.
-        * 
-        * @param this                          calling object
-        * @return                                      iterator for crlDistributionPoints
-        */
-       iterator_t *(*create_crluri_iterator) (const x509_t *this);
-
-       /**
-        * @brief Create an iterator for the ocspAccessLocations.
-        * 
-        * @param this                          calling object
-        * @return                                      iterator for ocspAccessLocations
-        */
-       iterator_t *(*create_ocspuri_iterator) (const x509_t *this);
-
-       /**
-        * @brief Check if a certificate is trustworthy
-        * 
-        * @param this                  calling object
-        * @param signer                signer's RSA public key
-        */
-       bool (*verify) (const x509_t *this, const rsa_public_key_t *signer);
-
-       /**
-        * @brief Compare two certificates.
-        * 
-        * Comparison is done via the certificates signature.
-        * 
-        * @param this                  first cert for compare
-        * @param other                 second cert for compare
-        * @return                              TRUE if signature is equal
-        */
-       bool (*equals) (const x509_t *this, const x509_t *that);
-
-       /**
-        * @brief Checks if the certificate contains a subjectAltName equal to id.
-        * 
-        * @param this                  certificate being examined
-        * @param id                    id which is being compared to the subjectAltNames
-        * @return                              TRUE if a match is found
-        */
-       bool (*equals_subjectAltName) (const x509_t *this, identification_t *id);
-
-       /**
-        * @brief Checks if the subject of the other cert is the issuer of this cert.
-        * 
-        * @param this                  certificate
-        * @param issuer                potential issuer certificate
-        * @return                              TRUE if issuer is found
-        */
-       bool (*is_issuer) (const x509_t *this, const x509_t *issuer);
-
-       /**
-        * @brief Checks the validity interval of the certificate
-        * 
-        * @param this                  certificate being examined
-        * @param until                 until = min(until, notAfter)
-        * @return                              NULL if the certificate is valid
-        */
-       err_t (*is_valid) (const x509_t *this, time_t *until);
-
-       /**
-        * @brief Returns the CA basic constraints flag
-        * 
-        * @param this                  certificate being examined
-        * @return                              TRUE if the CA flag is set
-        */
-       bool (*is_ca) (const x509_t *this);
-
-       /**
-        * @brief Returns the OCSPSigner extended key usage flag
-        * 
-        * @param this                  certificate being examined
-        * @return                              TRUE if the OCSPSigner flag is set
-        */
-       bool (*is_ocsp_signer) (const x509_t *this);
-
-       /**
-        * @brief Checks if the certificate is self-signed (subject equals issuer)
-        * 
-        * @param this                  certificate being examined
-        * @return                              TRUE if self-signed
-        */
-       bool (*is_self_signed) (const x509_t *this);
-       
-       /**
-        * @brief Log the certificate info to out.
-        *
-        * @param this                  calling object
-        * @param out                   stream to write to
-        * @param utc                   TRUE for UTC times, FALSE for local time
-        */
-       void (*list) (x509_t *this, FILE *out, bool utc);
-       
-       /**
-        * @brief Adds a list of subjectAltNames
-        * 
-        * @param this                          calling object
-        * @param subjectAltNames       list of subjectAltNames to be added
-        */
-       void (*add_subjectAltNames) (x509_t *this, linked_list_t *subjectAltNames);
-
-       /**
-        * @brief Builds a DER-encoded signed X.509 certificate
-        * 
-        * @param this                  calling object
-        * @param alg                   hash algorithm used to compute the certificate digest
-        * @param private_key   RSA private key used to sign the certificate digest
-        */
-       void (*build_encoding) (x509_t *this, hash_algorithm_t alg, rsa_private_key_t *private_key);
-
-       /**
-        * @brief Destroys the certificate.
-        * 
-        * @param this                  certificate to destroy
-        */
-       void (*destroy) (x509_t *this);
-};
-
-/**
- * @brief Create a X.509 certificate from its components
- *
- * @param serialNumber chunk containing the serialNumber
- * @param issuer               issuer distinguished name
- * @param notBefore            start date of validity
- * @param notAfter             end date of validity
- * @param subject              subject distinguished name
- * @param public_key   public key
- *
- * @return                             created x509_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509_t *x509_create(chunk_t serialNumber, identification_t *issuer,
-                                       time_t notBefore, time_t notAfter,
-                                       identification_t *subject,
-                                       rsa_public_key_t *public_key);
-
-/**
- * @brief Read a X.509 certificate from a DER encoded blob.
- *
- * @param chunk        chunk containing DER encoded data
- * @return                     created x509_t certificate, or NULL if invalid.
- * 
- * @ingroup crypto
- */
-x509_t *x509_create_from_chunk(chunk_t chunk, u_int level);
-
-/**
- * @brief Read a X.509 certificate from a DER encoded file.
- * 
- * @param filename     file containing DER encoded data
- * @param label                label describing kind of certificate
- * @return                     created x509_t certificate, or NULL if invalid.
- * 
- * @ingroup crypto
- */
-x509_t *x509_create_from_file(const char *filename, const char *label);
-
-/**
- * @brief Parses a DER encoded authorityKeyIdentifier
- * 
- * @param blob                                         blob containing DER encoded data
- * @param level0                               indicates the current parsing level
- * @param authKeyID                            assigns the authorityKeyIdentifier
- * @param authKeySerialNumber  assigns the authKeySerialNumber
- * 
- * @ingroup crypto
- */
-void x509_parse_authorityKeyIdentifier(chunk_t blob, int level0, chunk_t *authKeyID, chunk_t *authKeySerialNumber);
-
-/**
- * @brief Parses DER encoded generalNames
- * 
- * @param blob                         blob containing DER encoded data
- * @param level0               indicates the current parsing level
- * @param implicit             implicit coding is used
- * @param list                 list of decoded generalNames
- * 
- * @ingroup crypto
- */
-void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list);
-
-/**
- * @brief Builds a DER encoded list of generalNames
- * 
- * @param list                 list of generalNames to be encoded
- * @return                             DER encoded list of generalNames
- * 
- * @ingroup crypto
- */
-chunk_t x509_build_generalNames(linked_list_t *list);
-
-/**
- * @brief Builds a DER encoded list of subjectAltNames
- * 
- * @param list                 list of subjectAltNames to be encoded
- * @return                             DER encoded list of subjectAltNames
- * 
- * @ingroup crypto
- */
-chunk_t x509_build_subjectAltNames(linked_list_t *list);
-
-#endif /* X509_H_ */
diff --git a/src/libstrongswan/database/database.h b/src/libstrongswan/database/database.h
new file mode 100644 (file)
index 0000000..3ed09ee
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup database database
+ * @{ @ingroup database
+ */
+
+#ifndef DATABASE_H_
+#define DATABASE_H_
+
+typedef enum db_type_t db_type_t;
+typedef struct database_t database_t;
+
+#include <utils/enumerator.h>
+
+/**
+ * Database column types
+ */
+enum db_type_t {
+       /** integer type, argument is an "int" */
+       DB_INT,
+       /** unsigned integer, argument is an "u_int" */
+       DB_UINT,
+       /** string type, argument is a "char*" */
+       DB_TEXT,
+       /** binary large object type, argument is a "chunk_t" */
+       DB_BLOB,
+       /** floating point, argument is a "double" */
+       DB_DOUBLE,
+       /** NULL, takes no argument */
+       DB_NULL,
+};
+
+
+/**
+ * Interface for a database implementation.
+ *
+ * @code
+   int affected, rowid, aint;
+   char *atext;
+   database_t *db;
+   enumerator_t *enumerator;
+   
+   db = lib->database->create("mysql://user:pass@host/database");
+   affected = db->execute(db, &rowid, "INSERT INTO table VALUES (?, ?)",
+                                                 DB_INT, 77, DB_TEXT, "a text");
+   printf("inserted %d row, new row ID: %d\n", affected, rowid);
+   
+   enumerator = db->query(db, "SELECT aint, atext FROM table WHERE aint > ?",
+                                                 DB_INT, 10,           // 1 argument to SQL string
+                                                 DB_INT, DB_TEXT); // 2 enumerated types in query
+   if (enumerator)
+   {
+       while (enumerator->enumerate(enumerator, &aint, &atext))
+       {
+           printf("%d: %s\n", aint, atext);
+       }
+       enumerator->destroy(enumerator);
+   }
+   @endcode
+ */
+struct database_t {
+       
+       /**
+        * Run a query which returns rows, such as a SELECT.
+        *
+        * @param sql           sql query string, containing '?' placeholders
+        * @param ...           list of sql placeholder db_type_t followed by its value,
+        *                  followed by enumerators arguments as db_type_t's
+        * @return                      enumerator as defined with arguments, NULL on failure
+        */
+       enumerator_t* (*query)(database_t *this, char *sql, ...);
+       
+       /**
+        * Execute a query which dows not return rows, such as INSERT.
+        *
+        * @param rowid         pointer to write inserted AUTO_INCREMENT row ID, or NULL
+        * @param sql           sql string, containing '?' placeholders
+        * @param ...           list of sql placeholder db_type_t followed by its value
+        * @return                      number of affected rows, < 0 on failure
+        */
+       int (*execute)(database_t *this, int *rowid, char *sql, ...);
+       
+       /**
+     * Destroy a database connection.
+     */
+    void (*destroy)(database_t *this);
+};
+
+#endif /* DATABASE_H_ @}*/
diff --git a/src/libstrongswan/database/database_factory.c b/src/libstrongswan/database/database_factory.c
new file mode 100644 (file)
index 0000000..e725503
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "database_factory.h"
+
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+typedef struct private_database_factory_t private_database_factory_t;
+
+/**
+ * private data of database_factory
+ */
+struct private_database_factory_t {
+
+       /**
+        * public functions
+        */
+       database_factory_t public;
+       
+       /**
+        * list of registered database_t implementations
+        */
+       linked_list_t *databases;
+       
+       /**
+        * mutex to lock access to databases
+        */
+       mutex_t *mutex;
+};
+
+/**
+ * Implementation of database_factory_t.create.
+ */
+static database_t* create(private_database_factory_t *this, char *uri)
+{
+       enumerator_t *enumerator;
+       database_t *database = NULL;
+       database_constructor_t create;
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->databases->create_enumerator(this->databases);
+       while (enumerator->enumerate(enumerator, &create))
+       {
+               database = create(uri);
+               if (database)
+               {
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return database;
+}
+
+/**
+ * Implementation of database_factory_t.add_database.
+ */
+static void add_database(private_database_factory_t *this,
+                                                database_constructor_t create)
+{
+       this->mutex->lock(this->mutex);
+       this->databases->insert_last(this->databases, create);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of database_factory_t.remove_database.
+ */
+static void remove_database(private_database_factory_t *this,
+                                                       database_constructor_t create)
+{
+       this->mutex->lock(this->mutex);
+       this->databases->remove(this->databases, create, NULL);
+       this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of database_factory_t.destroy
+ */
+static void destroy(private_database_factory_t *this)
+{
+       this->databases->destroy(this->databases);
+       this->mutex->destroy(this->mutex);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+database_factory_t *database_factory_create()
+{
+       private_database_factory_t *this = malloc_thing(private_database_factory_t);
+       
+       this->public.create = (database_t*(*)(database_factory_t*, char *url))create;
+       this->public.add_database = (void(*)(database_factory_t*, database_constructor_t))add_database;
+       this->public.remove_database = (void(*)(database_factory_t*, database_constructor_t))remove_database;
+       this->public.destroy = (void(*)(database_factory_t*))destroy;
+       
+       this->databases = linked_list_create();
+       this->mutex = mutex_create(MUTEX_DEFAULT);
+       
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/database/database_factory.h b/src/libstrongswan/database/database_factory.h
new file mode 100644 (file)
index 0000000..358f490
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup database_factory database_factory
+ * @{ @ingroup database
+ */
+
+#ifndef DATABASE_FACTORY_H_
+#define DATABASE_FACTORY_H_
+
+typedef struct database_factory_t database_factory_t;
+
+#include <database/database.h>
+
+/**
+ * Generic database construction function.
+ *
+ * @param uri                  implementation specific connection URI
+ */
+typedef database_t*(*database_constructor_t)(char *uri);
+
+/**
+ * Create instances of database connections using registered constructors.
+ */
+struct database_factory_t {
+
+       /**
+        * Create a database connection instance.
+        *
+        * @param uri           implementation specific connection URI
+        * @return                      database_t instance, NULL if not supported/failed
+        */
+       database_t* (*create)(database_factory_t *this, char *uri);
+       
+       /**
+        * Register a database constructor.
+        *
+        * @param create        database constructor to register
+        */
+       void (*add_database)(database_factory_t *this, database_constructor_t create);
+       
+       /**
+        * Unregister a previously registered database constructor.
+        *
+        * @param create        database constructor to unregister
+        */
+       void (*remove_database)(database_factory_t *this, database_constructor_t create);
+       
+       /**
+     * Destroy a database_factory instance.
+     */
+    void (*destroy)(database_factory_t *this);
+};
+
+/**
+ * Create a database_factory instance.
+ */
+database_factory_t *database_factory_create();
+
+#endif /* DATABASE_FACTORY_H_ @}*/
index a71e978b8634aaa68d2873f154815fd15fa29831..a5a50966573b86c985b6e71e6678c627e76abd28 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file library.c
- *
- * @brief Logging functions for the library.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 <stdarg.h>
index 71f2c7dfdfc5b17aab02a457513ae585c2f8839e..611569c7ac1fa7acf2ded318099486fb29fd5739 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file log.h
- *
- * @brief Logging functions for the library.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 debug debug
+ * @{ @ingroup libstrongswan
  */
 
 #ifndef DEBUG_H_
@@ -60,4 +60,4 @@ extern void (*dbg) (int level, char *fmt, ...);
 /** default logging function, prints to stderr */
 void dbg_default(int level, char *fmt, ...);
 
-#endif /* DEBUG_H_ */
+#endif /* DEBUG_H_ @} */
index ade7c16a17bd0c1818f700ade7f573df956152bd..724246e25b09574342dc1f1b8f15df1860adb354 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file library.c
- *
- * @brief enum value to string conversion functions.
- *
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 <stddef.h>
@@ -46,7 +41,7 @@ static char *enum_name(enum_name_t *e, int val)
 /**
  * output handler in printf() for enum names
  */
-static int print_enum(FILE *stream, const struct printf_info *info,
+static int print(FILE *stream, const struct printf_info *info,
                                          const void *const *args)
 {
        enum_name_t *ed = *((enum_name_t**)(args[0]));
@@ -65,9 +60,25 @@ static int print_enum(FILE *stream, const struct printf_info *info,
 }
 
 /**
- * register printf() handlers
+ * arginfo handler for printf() hook
+ */
+static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+       if (n > 1)
+       {
+               argtypes[0] = PA_POINTER;
+               argtypes[1] = PA_INT;
+       }
+       return 2;
+}
+
+/**
+ * return printf hook functions
  */
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t enum_get_printf_hooks()
 {
-       register_printf_function(PRINTF_ENUM, print_enum, arginfo_ptr_int);
+       printf_hook_functions_t hooks = {print, arginfo};
+       
+       return hooks;
 }
+
index cd06e424b1cf807270a6c51b0b842b1fb100a7fe..cbf15de73aa1534b4ecb69bbbe6d3b9b2ec77e21 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file enum.h
- *
- * @brief enum value to string conversion functions.
- *
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 enum enum
+ * @{ @ingroup libstrongswan
  */
 
 #ifndef ENUM_H_
 #define ENUM_H_
 
+#include <printf_hook.h>
+
 typedef struct enum_name_t enum_name_t;
 
 /**
- * @brief Struct to store names for enums.
+ * Struct to store names for enums.
  *
  * To print the string representation of enumeration values, the strings
  * are stored in these structures. Every enum_name contains a range
@@ -34,14 +36,16 @@ typedef struct enum_name_t enum_name_t;
  * Use the convenience macros to define these linked ranges.
  *
  * For a single range, use:
- * ENUM(name, first, last, string1, string2, ...)
- *
+ * @code
+   ENUM(name, first, last, string1, string2, ...)
+   @endcode
  * For multiple linked ranges, use:
- * ENUM_BEGIN(name, first, last, string1, string2, ...)
- *   ENUM_NEXT(name, first, last, last_from_previous, string3, ...)
- *   ENUM_NEXT(name, first, last, last_from_previous, string4, ...)
- * ENUM_END(name, last_from_previous)
- *
+ * @code
+   ENUM_BEGIN(name, first, last, string1, string2, ...)
+     ENUM_NEXT(name, first, last, last_from_previous, string3, ...)
+     ENUM_NEXT(name, first, last, last_from_previous, string4, ...)
+   ENUM_END(name, last_from_previous)
+   @endcode
  * The ENUM and the ENUM_END define a enum_name_t pointer with the name supplied
  * in "name".
  *
@@ -62,7 +66,7 @@ struct enum_name_t {
 };
 
 /**
- * @brief Begin a new enum_name list.
+ * Begin a new enum_name list.
  *
  * @param name name of the enum_name list
  * @param first        enum value of the first enum string
@@ -72,7 +76,7 @@ struct enum_name_t {
 #define ENUM_BEGIN(name, first, last, ...) static enum_name_t name##last = {first, last, NULL, { __VA_ARGS__ }}
 
 /**
- * @brief Continue a enum name list startetd with ENUM_BEGIN.
+ * Continue a enum name list startetd with ENUM_BEGIN.
  *
  * @param name name of the enum_name list
  * @param first        enum value of the first enum string
@@ -83,7 +87,7 @@ struct enum_name_t {
 #define ENUM_NEXT(name, first, last, prev, ...) static enum_name_t name##last = {first, last, &name##prev, { __VA_ARGS__ }}
 
 /**
- * @brief Complete enum name list started with ENUM_BEGIN.
+ * Complete enum name list started with ENUM_BEGIN.
  *
  * @param name name of the enum_name list
  * @param prev enum value of the "last" defined in ENUM_BEGIN/previous ENUM_NEXT
@@ -91,7 +95,7 @@ struct enum_name_t {
 #define ENUM_END(name, prev) enum_name_t *name = &name##prev;
 
 /**
- * @brief Define a enum name with only one range.
+ * Define a enum name with only one range.
  *
  * This is a convenience macro to use when a enum_name list contains only
  * one range, and is equal as defining ENUM_BEGIN followed by ENUM_END.
@@ -103,4 +107,13 @@ struct enum_name_t {
  */
 #define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last)
 
-#endif /* ENUM_H_ */
+/**
+ * Get printf hook functions for enum_names_t.
+ *
+ * The handler takes the arguments: enum_names_t *names, int value
+ *
+ * @return             printf hook functions
+ */
+printf_hook_functions_t enum_get_printf_hooks();
+
+#endif /* ENUM_H_ @}*/
diff --git a/src/libstrongswan/fetcher/fetcher.h b/src/libstrongswan/fetcher/fetcher.h
new file mode 100644 (file)
index 0000000..5cd021d
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup fetcher fetcher
+ * @{ @ingroup fetcher
+ */
+
+#ifndef FETCHER_H_
+#define FETCHER_H_
+
+typedef struct fetcher_t fetcher_t;
+typedef enum fetcher_option_t fetcher_option_t;
+
+#include <stdarg.h>
+
+#include <library.h>
+
+/**
+ * Fetching options to use for fetcher_t.fetch() call.
+ */
+enum fetcher_option_t {
+
+       /** 
+        * Data to include in fetch request, e.g. on a HTTP post.
+        * Additional argument is a chunk_t
+        */
+       FETCH_REQUEST_DATA,
+       
+       /** 
+        * Mime-Type of data included in FETCH_REQUEST_DATA.
+        * Additional argument is a char*.
+        */
+       FETCH_REQUEST_TYPE,
+       
+       /** 
+        * Timeout to use for fetch, in seconds.
+        * Additional argument is u_int
+        */
+       FETCH_TIMEOUT,
+       
+       /**
+        * end of fetching options
+        */
+       FETCH_END,
+};
+
+/**
+ * Constructor function which creates fetcher instances.
+ *
+ * @return                     fetcher instance
+ */
+typedef fetcher_t* (*fetcher_constructor_t)();
+
+/**
+ * Fetcher interface, an implementation fetches data from an URL.
+ */
+struct fetcher_t {
+
+       /**
+        * Fetch data from URI into chunk.
+        *
+        * The fetcher returns NOT_SUPPORTED to indicate that it is uncappable
+        * to handle such URLs. Other return values indicate a failure, and
+        * fetching of that URL gets cancelled.
+        *
+        * @param uri           URI to fetch from
+        * @param result        chunk which receives allocated data
+        * @return
+        *                                      - SUCCESS if fetch was successful
+        *                                      - NOT_SUPPORTED if fetcher does not support such URLs
+        *                                      - FAILED, NOT_FOUND, PARSE_ERROR on failure
+        */
+       status_t (*fetch)(fetcher_t *this, char *uri, chunk_t *result);
+       
+       /**
+        * Set a fetcher option, as defined in fetcher_option_t.
+        *
+        * Arguments passed to options must stay in memory until fetch() returns.
+        *
+        * @param option        option to set
+        * @param ...           variable argument(s) to option
+        * @return                      TRUE if option supported, FALSE otherwise
+        */
+       bool (*set_option)(fetcher_t *this, fetcher_option_t option, ...);
+       
+       /**
+        * Destroy the fetcher instance.
+        */
+       void (*destroy)(fetcher_t *this);       
+};
+
+#endif /* FETCHER_H_ @}*/
diff --git a/src/libstrongswan/fetcher/fetcher_manager.c b/src/libstrongswan/fetcher/fetcher_manager.c
new file mode 100644 (file)
index 0000000..2866796
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "fetcher_manager.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+typedef struct private_fetcher_manager_t private_fetcher_manager_t;
+
+/**
+ * private data of fetcher_manager
+ */
+struct private_fetcher_manager_t {
+
+       /**
+        * public functions
+        */
+       fetcher_manager_t public;
+       
+       /**
+        * list of registered fetchers, as entry_t
+        */
+       linked_list_t *fetchers;
+       
+       /**
+        * read write lock to list
+        */
+       pthread_rwlock_t lock;
+};
+
+typedef struct {
+       /** assocaited fetcher construction function */
+       fetcher_constructor_t create;
+       /** URL this fetcher support */
+       char *url;
+} entry_t;
+
+/**
+ * destroy an entry_t
+ */
+static void entry_destroy(entry_t *entry)
+{
+       free(entry->url);
+       free(entry);
+}
+
+/**
+ * Implementation of fetcher_manager_t.fetch.
+ */
+static status_t fetch(private_fetcher_manager_t *this,
+                                         char *url, chunk_t *response, ...)
+{
+       enumerator_t *enumerator;
+       status_t status = NOT_SUPPORTED;
+       entry_t *entry;
+       bool capable = FALSE;
+       
+       pthread_rwlock_rdlock(&this->lock);
+       enumerator = this->fetchers->create_enumerator(this->fetchers);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               fetcher_option_t opt;
+               fetcher_t *fetcher;
+               bool good = TRUE;
+               va_list args;
+
+               /* check URL support of fetcher */
+               if (strncasecmp(entry->url, url, strlen(entry->url)))
+               {
+                       continue;
+               }
+               /* create fetcher instance and set options */
+               fetcher = entry->create();
+               if (!fetcher)
+               {
+                       continue;
+               }
+               va_start(args, response);
+               while (good)
+               {
+                       opt = va_arg(args, fetcher_option_t);
+                       switch (opt)
+                       {
+                               case FETCH_REQUEST_DATA:
+                                       good = fetcher->set_option(fetcher, opt, va_arg(args, chunk_t));
+                                       continue;
+                               case FETCH_REQUEST_TYPE:
+                                       good = fetcher->set_option(fetcher, opt, va_arg(args, char*));
+                                       continue;
+                               case FETCH_TIMEOUT:
+                                       good = fetcher->set_option(fetcher, opt, va_arg(args, u_int));
+                                       continue;
+                               case FETCH_END:
+                                       break;;
+                       }
+                       break;
+               }
+               va_end(args);
+               if (!good)
+               {       /* fetcher does not support supplied options, try another */
+                       fetcher->destroy(fetcher);
+                       continue;
+               }
+               
+               status = fetcher->fetch(fetcher, url, response);
+               fetcher->destroy(fetcher);
+               /* try another fetcher only if this one does not support that URL */
+               if (status == NOT_SUPPORTED)
+               {
+                       continue;
+               }
+               capable = TRUE;
+               break;
+       }
+       enumerator->destroy(enumerator);
+       pthread_rwlock_unlock(&this->lock);
+       if (!capable)
+       {
+               DBG1("unable to fetch from %s, no capable fetcher found", url);
+       }
+       return status;
+}
+
+/**
+ * Implementation of fetcher_manager_t.add_fetcher.
+ */
+static void add_fetcher(private_fetcher_manager_t *this,       
+                                               fetcher_constructor_t create, char *url)
+{
+       entry_t *entry = malloc_thing(entry_t);
+       
+       entry->url = strdup(url);
+       entry->create = create;
+
+       pthread_rwlock_wrlock(&this->lock);
+       this->fetchers->insert_last(this->fetchers, entry);
+       pthread_rwlock_unlock(&this->lock);
+}
+
+/**
+ * Implementation of fetcher_manager_t.remove_fetcher.
+ */
+static void remove_fetcher(private_fetcher_manager_t *this,
+                                                  fetcher_constructor_t create)
+{
+       enumerator_t *enumerator;
+       entry_t *entry;
+       
+       pthread_rwlock_wrlock(&this->lock);
+       enumerator = this->fetchers->create_enumerator(this->fetchers);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create == create)
+               {
+                       this->fetchers->remove_at(this->fetchers, enumerator);
+                       entry_destroy(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       pthread_rwlock_unlock(&this->lock);
+}
+
+/**
+ * Implementation of fetcher_manager_t.destroy
+ */
+static void destroy(private_fetcher_manager_t *this)
+{
+       this->fetchers->destroy_function(this->fetchers, (void*)entry_destroy);
+       pthread_rwlock_destroy(&this->lock);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+fetcher_manager_t *fetcher_manager_create()
+{
+       private_fetcher_manager_t *this = malloc_thing(private_fetcher_manager_t);
+       
+       this->public.fetch = (status_t(*)(fetcher_manager_t*, char *url, chunk_t *response, ...))fetch;
+       this->public.add_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t,char*))add_fetcher;
+       this->public.remove_fetcher = (void(*)(fetcher_manager_t*, fetcher_constructor_t))remove_fetcher;
+       this->public.destroy = (void(*)(fetcher_manager_t*))destroy;
+       
+       this->fetchers = linked_list_create();
+       pthread_rwlock_init(&this->lock, NULL);
+       
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/fetcher/fetcher_manager.h b/src/libstrongswan/fetcher/fetcher_manager.h
new file mode 100644 (file)
index 0000000..e94d444
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup fetcher_manager fetcher_manager
+ * @{ @ingroup fetcher
+ */
+
+#ifndef FETCHER_MANAGER_H_
+#define FETCHER_MANAGER_H_
+
+typedef struct fetcher_manager_t fetcher_manager_t;
+
+#include <fetcher/fetcher.h>
+
+/**
+ * Fetches from URIs using registerd fetcher_t instances.
+ */
+struct fetcher_manager_t {
+
+       /**
+        * Fetch data from URI into chunk.
+        *
+        * The variable argument list contains fetcher_option_t's, followed
+        * by a option specific data argument.
+        *
+        * @param uri                   URI to fetch from
+        * @param result                chunk which receives allocated data
+        * @param options               FETCH_END terminated fetcher_option_t arguments
+        * @return                              status indicating result of fetch
+        */
+       status_t (*fetch)(fetcher_manager_t *this, char *url, chunk_t *response, ...);
+
+       /**
+        * Register a fetcher implementation.
+        *
+        * @param constructor   fetcher constructor function
+        * @param url                   URL type this fetcher fetches, e.g. "http://"
+        */
+       void (*add_fetcher)(fetcher_manager_t *this,
+                                               fetcher_constructor_t constructor, char *url);
+       
+       /**
+        * Unregister a previously registered fetcher implementation.
+        *
+        * @param constructor   fetcher constructor function to unregister
+        */
+       void (*remove_fetcher)(fetcher_manager_t *this, 
+                                                  fetcher_constructor_t constructor);
+       
+       /**
+     * Destroy a fetcher_manager instance.
+     */
+    void (*destroy)(fetcher_manager_t *this);
+};
+
+/**
+ * Create a fetcher_manager instance.
+ */
+fetcher_manager_t *fetcher_manager_create();
+
+#endif /* FETCHER_MANAGER_H_ @}*/
index aba292d812f581303daa146195a41337f54b2d19..6701e1f5dffb64f80f10d24005f2a9330ab302c0 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file fips.c
- * 
- * @brief Implementation of the libstrongswan integrity test.
- * 
- */
-
 /*
  * Copyright (C) 2007 Bruno Krieg, Daniel Wydler
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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>
index decf73bfd531533e070e82678510c3a08fc485dc..f252ad6d1b4b39c064222e07380db6d2ca5ffff2 100644 (file)
@@ -1,11 +1,3 @@
-/**
- * @file fips.h
- * 
- * @brief Interface of the libstrongswan integrity test
- *
- * @ingroup fips
- */
-
 /*
  * Copyright (C) 2007 Bruno Krieg, Daniel Wydler
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 fips fips
+ * @{ @ingroup fips
  */
 
 #ifndef FIPS_H_
 #include <library.h>
 
 /**
- * @brief compute HMAC signature over RODATA and TEXT sections of libstrongswan
+ * compute HMAC signature over RODATA and TEXT sections of libstrongswan
  *
- * @param  key         key used for HMAC signature in ASCII string format
- * @param  signature   HMAC signature in HEX string format
- * @return             TRUE if HMAC signature computation was successful
+ * @param key          key used for HMAC signature in ASCII string format
+ * @param signature    HMAC signature in HEX string format
+ * @return                     TRUE if HMAC signature computation was successful
  */
 bool fips_compute_hmac_signature(const char *key, char *signature);
 
 /**
- * @brief verify HMAC signature over RODATA and TEXT sections of libstrongswan
+ * verify HMAC signature over RODATA and TEXT sections of libstrongswan
  *
- * @param  key         key used for HMAC signature in ASCII string format
- * @param  signature   signature value from fips_signature.h in HEX string format
- * @return             TRUE if signatures agree
+ * @param key          key used for HMAC signature in ASCII string format
+ * @param signature    signature value from fips_signature.h in HEX string format
+ * @return                     TRUE if signatures agree
  */
 bool fips_verify_hmac_signature(const char *key, const char *signature);
 
-#endif /*FIPS_H_*/
+#endif /*FIPS_H_ @} */
index 46d41a6640ec049586004c99fb59f7624a88964f..e210b6c090320bdb15a02a0a826b7a52a4ce801a 100644 (file)
@@ -1,14 +1,9 @@
-/**
- * @file fips_canister_end.c
- * 
- * @brief Marks the end of TEXT and RODATA.
- * 
- */
-
 /* ====================================================================
  * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
  * and usage in source and binary forms are granted according to the
  * OpenSSL license.
+ *
+ * $Id$
  */
 
 #include <stdio.h>
index eaf2571f8f2cc1b9aa01dc7b6114de7d979eb846..be8e226cfb5eb5067b215d3b5b2c06c3f5885e51 100644 (file)
@@ -1,14 +1,9 @@
-/**
- * @file fips_canister_start.c
- * 
- * @brief Marks the start of TEXT and RODATA.
- * 
- */
-
 /* ====================================================================
  * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
  * and usage in source and binary forms are granted according to the
  * OpenSSL license.
+ *
+ * $Id$
  */
 
 #include <stdio.h>
index 7fb61d5b75a3dc5550bb0a6d72c56ff047cc4413..d4679435c02e48d4c9c286c300c7aefb4201120f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file fips_signer.c
- * 
- * @brief Computes a HMAC signature and stores it in fips_signature.h.
- * 
- */
-
 /*
  * Copyright (C) 2007 Bruno Krieg, Daniel Wydler
  * Hochschule fuer Technik Rapperswil, Switzerland
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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>
@@ -57,7 +52,7 @@ int main(int argc, char* argv[])
        fprintf(f, "const char *hmac_key = \"%s\";\n", hmac_key);
        fprintf(f, "const char *hmac_signature = \"%s\";\n", hmac_signature);
        fprintf(f, "\n");
-       fprintf(f, "#endif /* FIPS_SIGNATURE_H_ */\n");
+       fprintf(f, "#endif /* FIPS_SIGNATURE_H_ @} */\n");
        fclose(f);
        exit(0);
 }
index f66818bc224ec142c59c524f9d82ab178e3fc877..e265a1a3e480ef40980add55c9bc710509ff78eb 100644 (file)
@@ -1,13 +1,5 @@
-/**
- * @file library.c
- *
- * @brief Helper functions and definitions.
- *
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
+ * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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>
-#include <time.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <pthread.h>
-
 #include "library.h"
 
-#include <printf_hook.h>
+#include <stdlib.h>
 
-ENUM(status_names, SUCCESS, DESTROY_ME,
-       "SUCCESS",
-       "FAILED",
-       "OUT_OF_RES",
-       "ALREADY_DONE",
-       "NOT_SUPPORTED",
-       "INVALID_ARG",
-       "NOT_FOUND",
-       "PARSE_ERROR",
-       "VERIFY_ERROR",
-       "INVALID_STATE",
-       "DESTROY_ME",
-       "NEED_MORE",
-);
+#include <utils.h>
+#include <chunk.h>
+#include <utils/identification.h>
+#include <utils/host.h>
+#include <utils/leak_detective.h>
 
-/**
- * Described in header.
- */
-void *clalloc(void * pointer, size_t size)
-{
-       void *data;
-       data = malloc(size);
-       
-       memcpy(data, pointer,size);
-       
-       return (data);
-}
+typedef struct private_library_t private_library_t;
 
 /**
- * Described in header.
+ * private data of library
  */
-void memxor(u_int8_t dest[], u_int8_t src[], size_t n)
-{
-       size_t i;
-       for (i = 0; i < n; i++)
-       {
-               dest[i] ^= src[i];
-       }
-}
+struct private_library_t {
 
-/**
- * We use a single mutex for all refcount variables. This
- * is not optimal for performance, but the critical section
- * is not that long...
- * TODO: Consider to include a mutex in each refcount_t variable.
- */
-static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
+       /**
+        * public functions
+        */
+       library_t public;
 
-/**
- * Described in header.
- * 
- * TODO: May be implemented with atomic CPU instructions
- * instead of a mutex.
- */
-void ref_get(refcount_t *ref)
-{
-       pthread_mutex_lock(&ref_mutex);
-       (*ref)++;
-       pthread_mutex_unlock(&ref_mutex);
-}
+#ifdef LEAK_DETECTIVE
+       /**
+        * Memory leak detective, if enabled
+        */
+       leak_detective_t *detective;
+#endif /* LEAK_DETECTIVE */
+};
 
 /**
- * Described in header.
- * 
- * TODO: May be implemented with atomic CPU instructions
- * instead of a mutex.
+ * library instance
  */
-bool ref_put(refcount_t *ref)
-{
-       bool more_refs;
-       
-       pthread_mutex_lock(&ref_mutex);
-       more_refs = --(*ref);
-       pthread_mutex_unlock(&ref_mutex);
-       return !more_refs;
-}
+library_t *lib;
 
 /**
- * output handler in printf() for time_t
+ * Implementation of library_t.destroy
  */
-static int print_time(FILE *stream, const struct printf_info *info,
-                                         const void *const *args)
+void library_deinit()
 {
-       static const char* months[] = {
-               "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-       };
-       time_t *time = *((time_t**)(args[0]));
-       bool utc = TRUE;
-       struct tm t;
+       private_library_t *this = (private_library_t*)lib;
+
+       this->public.plugins->destroy(this->public.plugins);
+       this->public.settings->destroy(this->public.settings);
+       this->public.creds->destroy(this->public.creds);
+       this->public.crypto->destroy(this->public.crypto);
+       this->public.fetcher->destroy(this->public.fetcher);
+       this->public.db->destroy(this->public.db);
+       this->public.printf_hook->destroy(this->public.printf_hook);
        
-       if (info->alt)
-       {
-               utc = *((bool*)(args[1]));
-       }
-       if (time == UNDEFINED_TIME)
-       {
-               return fprintf(stream, "--- -- --:--:--%s----",
-                                          info->alt ? " UTC " : " ");
-       }
-       if (utc)
-       {
-               gmtime_r(time, &t);
-       }
-       else
+#ifdef LEAK_DETECTIVE
+       if (this->detective)
        {
-               localtime_r(time, &t);
+               this->detective->destroy(this->detective);
        }
-       return fprintf(stream, "%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);
+#endif /* LEAK_DETECTIVE */
+       free(this);
+       lib = NULL;
 }
 
-/**
- * output handler in printf() for time deltas
+/*
+ * see header file
  */
-static int print_time_delta(FILE *stream, const struct printf_info *info,
-                                                       const void *const *args)
+void library_init(char *settings)
 {
-       char* unit = "second";
-       time_t *arg1, *arg2;
-       time_t delta;
+       printf_hook_t *pfh;
+       private_library_t *this = malloc_thing(private_library_t);
+       lib = &this->public;
        
-       arg1 = *((time_t**)(args[0]));
-       if (info->alt)
-       {
-               arg2 = *((time_t**)(args[1]));
-               delta = abs(*arg1 - *arg2);
-       }
-       else
-       {
-               delta = *arg1;
-       }
+#ifdef LEAK_DETECTIVE
+       this->detective = leak_detective_create();
+#endif /* LEAK_DETECTIVE */
 
-       if (delta > 2 * 60 * 60 * 24)
-       {
-               delta /= 60 * 60 * 24;
-               unit = "day";
-       }
-       else if (delta > 2 * 60 * 60)
-       {
-               delta /= 60 * 60;
-               unit = "hour";
-       }
-       else if (delta > 2 * 60)
-       {
-               delta /= 60;
-               unit = "minute";
-       }
-       return fprintf(stream, "%d %s%s", delta, unit, (delta == 1)? "":"s");
+       pfh = printf_hook_create();
+       this->public.printf_hook = pfh;
+       
+       pfh->add_handler(pfh, 'b', mem_get_printf_hooks());
+       pfh->add_handler(pfh, 'B', chunk_get_printf_hooks());
+       pfh->add_handler(pfh, 'D', identification_get_printf_hooks());
+       pfh->add_handler(pfh, 'H', host_get_printf_hooks());
+       pfh->add_handler(pfh, 'N', enum_get_printf_hooks());
+       pfh->add_handler(pfh, 'T', time_get_printf_hooks());
+       pfh->add_handler(pfh, 'V', time_delta_get_printf_hooks());
+       
+       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();
 }
 
-/**
- * register printf() handlers for time_t
- */
-static void __attribute__ ((constructor))print_register()
-{
-       register_printf_function(PRINTF_TIME, print_time, arginfo_ptr_alt_ptr_int);
-       register_printf_function(PRINTF_TIME_DELTA, print_time_delta, arginfo_ptr_alt_ptr_ptr);
-}
index bbe863fa093c19f56d5dfaabb30873b0b893fee3..9d151c4cccde70689d0e595f194fa409525a08f4 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file library.h
- *
- * @brief Helper functions and definitions.
- *
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
  */
 
-#ifndef LIBRARY_H_
-#define LIBRARY_H_
-
 /**
  * @defgroup libstrongswan libstrongswan
  *
- * libstrongswan: library with various cryptographic, X.509 trust chain and
- * identity management functions.
- */
-
-/**
  * @defgroup asn1 asn1
- *
- * ASN.1 definitions, parser and generator functions.
- *
  * @ingroup libstrongswan
- */
-
-/**
- * @defgroup crypto crypto
- *
- * Various cryptographic algorithms.
  *
+ * @defgroup credentials credentials
  * @ingroup libstrongswan
- */
-
-/**
- * @defgroup crypters crypters
- *
- * Symmetric encryption algorithms, used for
- * encryption and decryption.
- *
- * @ingroup crypto
- */
-
-/**
- * @defgroup hashers hashers
- *
- * Hashing algorithms, such as MD5 or SHA1
- *
- * @ingroup crypto
- */
-
-/**
- * @defgroup prfs prfs
- *
- * Pseudo random functions, used to generate 
- * pseude random byte sequences.
- *
- * @ingroup crypto
- */
-
-/**
- * @defgroup rsa rsa
- *
- * RSA private/public key algorithm.
  *
- * @ingroup crypto
- */
-
-/**
- * @defgroup signers signers
+ * @defgroup keys keys
+ * @ingroup credentials
  *
- * Symmetric signing algorithms, 
- * used to ensure message integrity.
+ * @defgroup certificates certificates
+ * @ingroup credentials
  *
- * @ingroup crypto
- */
-
-/**
+ * @defgroup crypto crypto
+ * @ingroup libstrongswan
+ * @defgroup database database
+ * @ingroup libstrongswan
+ * @defgroup fetcher fetcher
+ * @ingroup libstrongswan
  * @defgroup fips fips
- *
- * Code integrity check of libstrongswan
- *
  * @ingroup libstrongswan
- */
-
-/**
+ * @defgroup plugins plugins
+ * @ingroup libstrongswan
  * @defgroup utils utils
- *
- * Generic helper classes.
- *
  * @ingroup libstrongswan
  */
 
-#include <gmp.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <printf.h>
-
-#include <enum.h>
-
-/**
- * Number of bits in a byte
- */
-#define BITS_PER_BYTE 8
-
-/**
- * Default length for various auxiliary text buffers
- */
-#define BUF_LEN 512
-
-/**
- * Macro compares two strings for equality
- */
-#define streq(x,y) (strcmp(x, y) == 0)
-
-/**
- * Macro compares two strings for equality
- */
-#define strneq(x,y,len) (strncmp(x, y, len) == 0)
-
-/**
- * Macro compares two binary blobs for equality
- */
-#define memeq(x,y,len) (memcmp(x, y, len) == 0)
-
-/**
- * Macro gives back larger of two values.
- */
-#define max(x,y) ((x) > (y) ? (x):(y))
-
-/**
- * Macro gives back smaller of two values.
- */
-#define min(x,y) ((x) < (y) ? (x):(y))
-
-/**
- * Call destructor of an object, if object != NULL
- */
-#define DESTROY_IF(obj) if (obj) obj->destroy(obj)
-
-/**
- * Call offset destructor of an object, if object != NULL
- */
-#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
-
 /**
- * Call function destructor of an object, if object != NULL
+ * @defgroup library library
+ * @{ @ingroup libstrongswan
  */
-#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
 
-/**
- * Debug macro to follow control flow
- */
-#define POS printf("%s, line %d\n", __FILE__, __LINE__)
-
-/**
- * Macro to allocate a sized type.
- */
-#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
+#ifndef LIBRARY_H_
+#define LIBRARY_H_
 
-/**
- * Assign a function as a class method
- */
-#define ASSIGN(method, function) (method = (typeof(method))function)
+#include <utils.h>
+#include <chunk.h>
+#include <settings.h>
+#include <printf_hook.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>
 
-/**
- * time_t not defined
- */
-#define UNDEFINED_TIME 0
+typedef struct library_t library_t;
 
 /**
- * General purpose boolean type.
+ * Libstrongswan library context, contains library relevant globals.
  */
-typedef int bool;
-#define FALSE 0
-#define TRUE  1
-
-typedef enum status_t status_t;
+struct library_t {
 
-/**
- * Return values of function calls.
- */
-enum status_t {
-       /**
-        * Call succeeded.
-        */
-       SUCCESS,
-       
-       /**
-        * Call failed.
-        */
-       FAILED,
-       
-       /**
-        * Out of resources.
-        */
-       OUT_OF_RES,
-       
-       /**
-        * The suggested operation is already done
-        */
-       ALREADY_DONE,
-       
        /**
-        * Not supported.
+        * Printf hook registering facility
         */
-       NOT_SUPPORTED,
+       printf_hook_t *printf_hook;
        
        /**
-        * One of the arguments is invalid.
+        * crypto algorithm registry and factory
         */
-       INVALID_ARG,
+       crypto_factory_t *crypto;
        
        /**
-        * Something could not be found.
+        * credential constructor registry and factory
         */
-       NOT_FOUND,
+       credential_factory_t *creds;
        
        /**
-        * Error while parsing.
+        * URL fetching facility
         */
-       PARSE_ERROR,
+       fetcher_manager_t *fetcher;
        
        /**
-        * Error while verifying.
+        * database construction factory
         */
-       VERIFY_ERROR,
+       database_factory_t *db;
        
        /**
-        * Object in invalid state.
+        * plugin loading facility
         */
-       INVALID_STATE,
+       plugin_loader_t *plugins;
        
        /**
-        * Destroy object which called method belongs to.
+        * various settings loaded from settings file
         */
-       DESTROY_ME,
-       
-       /**
-        * Another call to the method is required.
-        */
-       NEED_MORE,
+       settings_t *settings;
 };
 
 /**
- * used by strict_crl_policy
- */
-typedef enum {
-       STRICT_NO,
-       STRICT_YES,
-       STRICT_IFURI
-} strict_t;
-
-/**
- * enum_names for type status_t.
- */
-extern enum_name_t *status_names;
-
-/**
- * deprecated pluto style return value:
- * error message, NULL for success
- */
-typedef const char *err_t;
-
-/**
- * Handle struct timeval like an own type.
- */
-typedef struct timeval timeval_t;
-
-/**
- * Handle struct timespec like an own type.
- */
-typedef struct timespec timespec_t;
-
-/**
- * Handle struct chunk_t like an own type.
- */
-typedef struct sockaddr sockaddr_t;
-
-/**
- * Clone a data to a newly allocated buffer
- */
-void *clalloc(void *pointer, size_t size);
-
-/**
- * Same as memcpy, but XORs src into dst instead of copy
- */
-void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
-
-/**
- * Special type to count references
+ * Initialize library, creates "lib" instance.
+ *
+ * @param settings             file to read settings from, may be NULL for none
  */
-typedef volatile u_int refcount_t;
+void library_init(char *settings);
 
 /**
- * @brief Get a new reference.
- *
- * Increments the reference counter atomic.
- *
- * @param ref  pointer to ref counter
+ * Deinitialize library, destroys "lib" instance.
  */
-void ref_get(refcount_t *ref);
+void library_deinit();
 
 /**
- * @brief Put back a unused reference.
- *
- * Decrements the reference counter atomic and 
- * says if more references available.
- *
- * @param ref  pointer to ref counter
- * @return             TRUE if no more references counted
+ * Library instance, set after between library_init() and library_deinit() calls.
  */
-bool ref_put(refcount_t *ref);
-
-
-#include <chunk.h>
-#include <printf_hook.h>
+extern library_t *lib;
 
-#endif /* LIBRARY_H_ */
+#endif /* LIBRARY_H_ @}*/
diff --git a/src/libstrongswan/plugins/aes/Makefile.am b/src/libstrongswan/plugins/aes/Makefile.am
new file mode 100644 (file)
index 0000000..e73040f
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-aes.la
+
+libstrongswan_aes_la_SOURCES = aes_plugin.h aes_plugin.c aes_crypter.c aes_crypter.h
+libstrongswan_aes_la_LDFLAGS = -module
+
similarity index 97%
rename from src/libstrongswan/crypto/crypters/aes_cbc_crypter.c
rename to src/libstrongswan/plugins/aes/aes_crypter.c
index 947188af3525ca5ea876d0f1ca5c075b1b829323..f0c31cfa260c1ee825e3995dbb6580a36793e8cc 100644 (file)
@@ -1,11 +1,4 @@
-/**
- * @file aes_cbc_crypter.c
- * 
- * @brief Implementation of aes_cbc_crypter_t
- * 
- */
- /*
+/*
  * Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net>
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 "aes_cbc_crypter.h"
-
-
+#include "aes_crypter.h"
 
 /*
  * The number of key schedule words for different block and key lengths
 
 #define AES_BLOCK_SIZE 16
 
-typedef struct private_aes_cbc_crypter_t private_aes_cbc_crypter_t;
+typedef struct private_aes_crypter_t private_aes_crypter_t;
 
 /**
- * @brief Class implementing the AES symmetric encryption algorithm.
+ * Class implementing the AES symmetric encryption algorithm.
  * 
  * @ingroup crypters
  */
-struct private_aes_cbc_crypter_t {
+struct private_aes_crypter_t {
        
        /**
         * Public part of this class.
         */
-       aes_cbc_crypter_t public;
+       aes_crypter_t public;
        
        /**
         * Number of words in the key input block.
@@ -91,7 +84,7 @@ struct private_aes_cbc_crypter_t {
        * @param[in] in_blk     block to decrypt
        * @param[out] out_blk   decrypted data are written to this location
        */
-       void (*decrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
+       void (*decrypt_block) (const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
        
        /**
        * Encrypts a block.
@@ -102,7 +95,7 @@ struct private_aes_cbc_crypter_t {
        * @param[in] in_blk     block to encrypt
        * @param[out] out_blk   encrypted data are written to this location
        */
-       void (*encrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
+       void (*encrypt_block) (const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
 };
 
 
@@ -1243,9 +1236,9 @@ switch(nc) \
 #endif
 
 /**
- * Implementation of private_aes_cbc_crypter_t.encrypt_block.
+ * Implementation of private_aes_crypter_t.encrypt_block.
  */
-static void encrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
+static void encrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
 {   u_int32_t        locals(b0, b1);
     const u_int32_t  *kp = this->aes_e_key;
 
@@ -1304,9 +1297,9 @@ static void encrypt_block(const private_aes_cbc_crypter_t *this, const unsigned
 }
 
 /**
- * Implementation of private_aes_cbc_crypter_t.decrypt_block.
+ * Implementation of private_aes_crypter_t.decrypt_block.
  */
-static void decrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
+static void decrypt_block(const private_aes_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
 {   u_int32_t        locals(b0, b1);
     const u_int32_t  *kp = this->aes_d_key;
 
@@ -1367,7 +1360,7 @@ static void decrypt_block(const private_aes_cbc_crypter_t *this, const unsigned
 /**
  * Implementation of crypter_t.decrypt.
  */
-static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
+static status_t decrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
 {
        int ret, pos;
        const u_int32_t *iv_i;
@@ -1415,7 +1408,7 @@ static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t
 /**
  * Implementation of crypter_t.decrypt.
  */
-static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
+static status_t encrypt (private_aes_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
 {
        int ret, pos;
        const u_int32_t *iv_i;
@@ -1460,7 +1453,7 @@ static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t
 /**
  * Implementation of crypter_t.get_block_size.
  */
-static size_t get_block_size (private_aes_cbc_crypter_t *this)
+static size_t get_block_size (private_aes_crypter_t *this)
 {
        return AES_BLOCK_SIZE;
 }
@@ -1468,7 +1461,7 @@ static size_t get_block_size (private_aes_cbc_crypter_t *this)
 /**
  * Implementation of crypter_t.get_key_size.
  */
-static size_t get_key_size (private_aes_cbc_crypter_t *this)
+static size_t get_key_size (private_aes_crypter_t *this)
 {
        return this->key_size;
 }
@@ -1476,7 +1469,7 @@ static size_t get_key_size (private_aes_cbc_crypter_t *this)
 /**
  * Implementation of crypter_t.set_key.
  */
-static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key)
+static status_t set_key (private_aes_crypter_t *this, chunk_t key)
 {
        u_int32_t    *kf, *kt, rci, f = 0;
        u_int8_t *in_key = key.ptr;
@@ -1570,9 +1563,9 @@ static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key)
 }
 
 /**
- * Implementation of crypter_t.destroy and aes_cbc_crypter_t.destroy.
+ * Implementation of crypter_t.destroy and aes_crypter_t.destroy.
  */
-static void destroy (private_aes_cbc_crypter_t *this)
+static void destroy (private_aes_crypter_t *this)
 {
        free(this);
 }
@@ -1580,16 +1573,24 @@ static void destroy (private_aes_cbc_crypter_t *this)
 /*
  * Described in header
  */
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size)
+aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo, size_t key_size)
 {
-       private_aes_cbc_crypter_t *this = malloc_thing(private_aes_cbc_crypter_t);
+       private_aes_crypter_t *this;
+       
+       if (algo != ENCR_AES_CBC)
+       {
+               return NULL;
+       }
+       
+       this = malloc_thing(private_aes_crypter_t);
        
        #if !defined(FIXED_TABLES)
        if(!tab_gen) { gen_tabs(); tab_gen = 1; }
        #endif
        
        this->key_size = key_size;
-       switch(key_size) {
+       switch(key_size)
+       {
        case 32:        /* bytes */
                this->aes_Nkey = 8;
                break;
similarity index 51%
rename from src/libstrongswan/crypto/crypters/aes_cbc_crypter.h
rename to src/libstrongswan/plugins/aes/aes_crypter.h
index 5da248b8c1d45dd9e33e65c7829df86efc28da93..e42a6bc5b00b3807836bc78f6bfd01cf01231e19 100644 (file)
@@ -1,13 +1,5 @@
-/**
- * @file aes_cbc_crypter.h
- * 
- * @brief Interface of aes_cbc_crypter_t
- * 
- */
-
 /*
- * Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net>
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * for more details.
  */
 
-#ifndef AES_CBC_CRYPTER_H_
-#define AES_CBC_CRYPTER_H_
+/**
+ * @defgroup aes_crypter aes_crypter
+ * @{ @ingroup aes_p
+ */
+
+#ifndef AES_CRYPTER_H_
+#define AES_CRYPTER_H_
 
-typedef struct aes_cbc_crypter_t aes_cbc_crypter_t;
+typedef struct aes_crypter_t aes_crypter_t;
 
 #include <crypto/crypters/crypter.h>
 
 /**
- * @brief Class implementing the AES symmetric encryption algorithm.
- *
- * @b Constructors:
- *  - aes_cbc_crypter_create()
- *
- * @ingroup crypters
+ * Class implementing the AES encryption algorithm.
  */
-struct aes_cbc_crypter_t {
+struct aes_crypter_t {
        
        /**
         * The crypter_t interface.
@@ -46,16 +38,13 @@ struct aes_cbc_crypter_t {
 };
 
 /**
- * @brief Constructor to create aes_cbc_crypter_t objects.
- * 
- * Supported key sizes are: 16, 24 or 32. 
+ * Constructor to create aes_crypter_t objects.
  * 
  * @param key_size             key size in bytes
- * @return                             
- *                                             - aes_cbc_crypter_t object
- *                                             - NULL if key size not supported
+ * @param algo                 algorithm to implement
+ * @return                             aes_crypter_t object, NULL if not supported
  */
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size);
-
+aes_crypter_t *aes_crypter_create(encryption_algorithm_t algo,
+                                                                 size_t key_size);
 
-#endif /* AES_CBC_CRYPTER_H_ */
+#endif /* AES_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/aes/aes_plugin.c b/src/libstrongswan/plugins/aes/aes_plugin.c
new file mode 100644 (file)
index 0000000..590948f
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "aes_plugin.h"
+
+#include <library.h>
+#include "aes_crypter.h"
+
+typedef struct private_aes_plugin_t private_aes_plugin_t;
+
+/**
+ * private data of aes_plugin
+ */
+struct private_aes_plugin_t {
+
+       /**
+        * public functions
+        */
+       aes_plugin_t public;
+};
+
+/**
+ * Implementation of aes_plugin_t.destroy
+ */
+static void destroy(private_aes_plugin_t *this)
+{
+       lib->crypto->remove_crypter(lib->crypto,
+                                                               (crypter_constructor_t)aes_crypter_create);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_aes_plugin_t *this = malloc_thing(private_aes_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
+                                                        (crypter_constructor_t)aes_crypter_create);
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/aes/aes_plugin.h b/src/libstrongswan/plugins/aes/aes_plugin.h
new file mode 100644 (file)
index 0000000..4cf0bc1
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup aes_p aes
+ * @ingroup plugins
+ *
+ * @defgroup aes_plugin aes_plugin
+ * @{ @ingroup aes_p
+ */
+
+#ifndef AES_PLUGIN_H_
+#define AES_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct aes_plugin_t aes_plugin_t;
+
+/**
+ * Plugin implementing AES based algorithms in software.
+ */
+struct aes_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a aes_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* AES_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/curl/Makefile.am b/src/libstrongswan/plugins/curl/Makefile.am
new file mode 100644 (file)
index 0000000..1b44516
--- /dev/null
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-curl.la
+
+libstrongswan_curl_la_SOURCES = curl_plugin.h curl_plugin.c curl_fetcher.c curl_fetcher.h
+libstrongswan_curl_la_LDFLAGS = -module
+libstrongswan_curl_la_LIBADD  = -lcurl
+
diff --git a/src/libstrongswan/plugins/curl/curl_fetcher.c b/src/libstrongswan/plugins/curl/curl_fetcher.c
new file mode 100644 (file)
index 0000000..fe49717
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 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.
+ *
+ * $Id$
+ */
+
+#include <curl/curl.h>
+
+#include <library.h>
+#include <debug.h>
+
+#include "curl_fetcher.h"
+
+#define DEFAULT_TIMEOUT 10
+
+typedef struct private_curl_fetcher_t private_curl_fetcher_t;
+
+/**
+ * private data of a curl_fetcher_t object.
+ */
+struct private_curl_fetcher_t {
+       /**
+        * Public data
+        */
+       curl_fetcher_t public;
+
+       /**
+        * CURL handle
+        */
+       CURL* curl;
+       
+       /**
+        * request type, as set with FETCH_REQUEST_TYPE
+        */
+       char *request_type;
+};
+
+/**
+ * writes data into a dynamically resizeable chunk_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)
+    {
+               memcpy(&data->ptr[data->len], ptr, realsize);
+               data->len += realsize;
+    }
+    return realsize;
+}
+
+/**
+ * Implements fetcher_t.fetch.
+ */
+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;
+       
+       if (curl_easy_setopt(this->curl, CURLOPT_URL, uri) != CURLE_OK)
+       {       /* URL type not supported by curl */
+               return NOT_SUPPORTED;
+       }
+       curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, error);
+       curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
+       curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
+       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)
+       {
+               snprintf(buf, sizeof(buf), "Content-Type: %s", this->request_type);
+               headers = curl_slist_append(headers, buf);
+               curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
+       }
+
+       DBG2("sending http request to '%s'...", uri);
+       switch (curl_easy_perform(this->curl))
+       {
+               case CURLE_UNSUPPORTED_PROTOCOL:
+                       status = NOT_SUPPORTED;
+                       break;
+               case CURLE_OK:
+                       status = SUCCESS;
+                       break;
+               default:
+               DBG1("libcurl http request failed: %s", error);
+                       status = FAILED;
+                       break;
+       }
+       curl_slist_free_all(headers);
+       return status;
+}
+
+/**
+ * Implementation of fetcher_t.set_option.
+ */
+static bool set_option(private_curl_fetcher_t *this, fetcher_option_t option, ...)
+{
+       va_list args;
+       
+       va_start(args, option);
+       switch (option)
+       {
+               case FETCH_REQUEST_DATA:
+               {
+                       chunk_t data = va_arg(args, chunk_t);
+                       curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, data.ptr);
+                       curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, data.len);
+                       return TRUE;
+               }
+               case FETCH_REQUEST_TYPE:
+               {
+                       this->request_type = va_arg(args, char*);
+                       return TRUE;
+               }
+               case FETCH_TIMEOUT:
+               {
+                       curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT,
+                                                        va_arg(args, u_int));
+                       return TRUE;
+               }
+               default:
+                       return FALSE;
+       }
+}
+
+/**
+ * Implements fetcher_t.destroy
+ */
+static void destroy(private_curl_fetcher_t *this)
+{
+       curl_easy_cleanup(this->curl);
+       free(this);
+}
+
+/*
+ * Described in header.
+ */
+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->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_fetcher.h b/src/libstrongswan/plugins/curl/curl_fetcher.h
new file mode 100644 (file)
index 0000000..3028eac
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup curl_fetcher curl_fetcher
+ * @{ @ingroup curl_p
+ */
+
+#ifndef CURL_FETCHER_H_
+#define CURL_FETCHER_H_
+
+typedef struct curl_fetcher_t curl_fetcher_t;
+
+/**
+ * Fetcher implementation using libcurl
+ */
+struct curl_fetcher_t {
+
+       /**
+        * Implements fetcher interface
+        */
+       fetcher_t interface;
+               
+       /**
+     * Destroy a curl_fetcher instance.
+     */
+    void (*destroy)(curl_fetcher_t *this);
+};
+
+/**
+ * Create a curl_fetcher instance.
+ */
+curl_fetcher_t *curl_fetcher_create();
+
+#endif /* CURL_FETCHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/curl/curl_plugin.c b/src/libstrongswan/plugins/curl/curl_plugin.c
new file mode 100644 (file)
index 0000000..04e9b17
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "curl_plugin.h"
+
+#include <library.h>
+#include <debug.h>
+#include "curl_fetcher.h"
+
+#include <curl/curl.h>
+
+typedef struct private_curl_plugin_t private_curl_plugin_t;
+
+/**
+ * private data of curl_plugin
+ */
+struct private_curl_plugin_t {
+
+       /**
+        * public functions
+        */
+       curl_plugin_t public;
+};
+
+/**
+ * Implementation of curl_plugin_t.curltroy
+ */
+static void destroy(private_curl_plugin_t *this)
+{
+       lib->fetcher->remove_fetcher(lib->fetcher,
+                                                                (fetcher_constructor_t)curl_fetcher_create);
+       curl_global_cleanup();
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       CURLcode res;
+       private_curl_plugin_t *this = malloc_thing(private_curl_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       res = curl_global_init(CURL_GLOBAL_NOTHING);
+       if (res == CURLE_OK)
+       {
+               lib->fetcher->add_fetcher(lib->fetcher,
+                                               (fetcher_constructor_t)curl_fetcher_create, "file://");
+               lib->fetcher->add_fetcher(lib->fetcher, 
+                                               (fetcher_constructor_t)curl_fetcher_create, "http://");
+               lib->fetcher->add_fetcher(lib->fetcher,
+                                               (fetcher_constructor_t)curl_fetcher_create, "https://");
+               lib->fetcher->add_fetcher(lib->fetcher, 
+                                               (fetcher_constructor_t)curl_fetcher_create, "ftp://");
+    }
+    else
+    {
+       DBG1("global libcurl initializing failed: %s, curl disabled", 
+                        curl_easy_strerror(res));
+    }
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/curl/curl_plugin.h b/src/libstrongswan/plugins/curl/curl_plugin.h
new file mode 100644 (file)
index 0000000..73166a2
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup curl_p curl
+ * @ingroup plugins
+ *
+ * @defgroup curl_plugin curl_plugin
+ * @{ @ingroup curl_p
+ */
+
+#ifndef CURL_PLUGIN_H_
+#define CURL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct curl_plugin_t curl_plugin_t;
+
+/**
+ * Plugin implementing fetcher interface using libcurl http library.
+ */
+struct curl_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a curl_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* CURL_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/des/Makefile.am b/src/libstrongswan/plugins/des/Makefile.am
new file mode 100644 (file)
index 0000000..ea94eda
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-des.la
+
+libstrongswan_des_la_SOURCES = des_plugin.h des_plugin.c des_crypter.c des_crypter.h
+libstrongswan_des_la_LDFLAGS = -module
+
similarity index 99%
rename from src/libstrongswan/crypto/crypters/des_crypter.c
rename to src/libstrongswan/plugins/des/des_crypter.c
index 655cc03ce1ba6c1e26c12a99036fa2e9ccea2e23..55c12ad8190fe6c1791506b3a676ab9dee903100 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file des_crypter.c
- *
- * @brief Implementation of des_crypter_t
- *
- */
-
 /* Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -61,6 +54,8 @@
  * 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$
  */
 
 #include "des_crypter.h"
similarity index 70%
rename from src/libstrongswan/crypto/crypters/des_crypter.h
rename to src/libstrongswan/plugins/des/des_crypter.h
index 0c87b0a9c9d0fbae3f775c2d906541c7d765f440..d40d9cf2fa9325bb48db3e59acc43927c17a61ea 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file des_crypter.h
- * 
- * @brief Interface of des_crypter_t
- * 
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * for more details.
  */
 
+/**
+ * @defgroup des_crypter des_crypter
+ * @{ @ingroup des_p
+ */
+
 #ifndef DES_CRYPTER_H_
 #define DES_CRYPTER_H_
 
@@ -29,12 +27,7 @@ typedef struct des_crypter_t des_crypter_t;
 
 
 /**
- * @brief Class implementing the DES and 3DES encryption algorithms.
- * 
- * @b Constructors:
- *  - des_crypter_create()
- * 
- * @ingroup crypters
+ * Class implementing the DES and 3DES encryption algorithms.
  */
 struct des_crypter_t {
        
@@ -45,14 +38,12 @@ struct des_crypter_t {
 };
 
 /**
- * @brief Constructor to create des_crypter_t objects.
+ * Constructor to create des_crypter_t objects.
  * 
  * @param algo         ENCR_DES for single DES, ENCR_3DES for triple DES
- * @return                             
- *                                     - des_crypter_t object
- *                                     - NULL if algo not supported
+ * @return                     des_crypter_t object, NULL if algo not supported
  */
 des_crypter_t *des_crypter_create(encryption_algorithm_t algo);
 
 
-#endif /* DES_CRYPTER_H_ */
+#endif /* DES_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/des/des_plugin.c b/src/libstrongswan/plugins/des/des_plugin.c
new file mode 100644 (file)
index 0000000..4fb98c1
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "des_plugin.h"
+
+#include <library.h>
+#include "des_crypter.h"
+
+typedef struct private_des_plugin_t private_des_plugin_t;
+
+/**
+ * private data of des_plugin
+ */
+struct private_des_plugin_t {
+
+       /**
+        * public functions
+        */
+       des_plugin_t public;
+};
+
+/**
+ * Implementation of des_plugin_t.destroy
+ */
+static void destroy(private_des_plugin_t *this)
+{
+       lib->crypto->remove_crypter(lib->crypto,
+                                                               (crypter_constructor_t)des_crypter_create);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_des_plugin_t *this = malloc_thing(private_des_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->crypto->add_crypter(lib->crypto, ENCR_DES,
+                                                        (crypter_constructor_t)des_crypter_create);
+       lib->crypto->add_crypter(lib->crypto, ENCR_3DES,
+                                                        (crypter_constructor_t)des_crypter_create);
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/des/des_plugin.h b/src/libstrongswan/plugins/des/des_plugin.h
new file mode 100644 (file)
index 0000000..8cabd08
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup des_p des
+ * @ingroup plugins
+ *
+ * @defgroup des_plugin des_plugin
+ * @{ @ingroup des_p
+ */
+
+#ifndef DES_PLUGIN_H_
+#define DES_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct des_plugin_t des_plugin_t;
+
+/**
+ * Plugin implementing DES based algorithms in software.
+ */
+struct des_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a des_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* DES_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.am b/src/libstrongswan/plugins/fips_prf/Makefile.am
new file mode 100644 (file)
index 0000000..73f2882
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-fips-prf.la
+
+libstrongswan_fips_prf_la_SOURCES = fips_prf_plugin.h fips_prf_plugin.c fips_prf.c fips_prf.h
+libstrongswan_fips_prf_la_LDFLAGS = -module
+
similarity index 83%
rename from src/libstrongswan/crypto/prfs/fips_prf.c
rename to src/libstrongswan/plugins/fips_prf/fips_prf.c
index 0ab80b089a77d25eee08fecc4453803f9ae81400..20b752e30e646cb19832c75e72a89846e1cc88a8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file fips_prf.c
- * 
- * @brief Implementation for fips_prf_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "fips_prf.h"
@@ -47,10 +42,15 @@ struct private_fips_prf_t {
         */
        size_t b;
        
+       /**
+        * associated hasher when using SHA1 mode
+        */
+       hasher_t *hasher;
+       
        /**
         * G function, either SHA1 or DES
         */
-       void (*g)(u_int8_t t[], chunk_t c, u_int8_t res[]);
+       void (*g)(private_fips_prf_t *this, u_int8_t t[], chunk_t c, u_int8_t res[]);
 };
 
 /**
@@ -61,6 +61,7 @@ static u_int8_t t[] = {
        0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
 };
 
+
 /**
  * sum = (a + b) mod 2 ^ (length * 8)
  */
@@ -139,7 +140,7 @@ static void get_bytes(private_fips_prf_t *this, chunk_t seed, u_int8_t w[])
                add_mod(this->b, xkey, xseed, xval);
                DBG3("XVAL %b", xval, this->b);
                /* b. wi = G(t, XVAL ) */
-               this->g(t, xval_chunk, &w[i * this->b]);
+               this->g(this, t, xval_chunk, &w[i * this->b]);
                DBG3("w[%d] %b", i, &w[i * this->b], this->b);
                /* c. XKEY = (1 + XKEY + wi) mod 2b */
                add_mod(this->b, xkey, &w[i * this->b], sum);
@@ -186,12 +187,9 @@ static void set_key(private_fips_prf_t *this, chunk_t key)
 /**
  * Implementation of the G() function based on SHA1
  */
-void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
+void g_sha1(private_fips_prf_t *this, u_int8_t t[], chunk_t c, u_int8_t res[])
 {
-       hasher_t *hasher;
        u_int8_t buf[64];
-       chunk_t state_chunk;
-       u_int32_t *state, *iv, *hash;
        
        if (c.len < sizeof(buf))
        {
@@ -207,24 +205,8 @@ void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
                c.len = sizeof(buf);
        }
        
-       /* our SHA1 hasher's state is 32-Bit integers in host order. We must
-        * convert them */
-       hasher = hasher_create(HASH_SHA1);
-       state_chunk = hasher->get_state(hasher);
-       state = (u_int32_t*)state_chunk.ptr;
-       iv = (u_int32_t*)t;
-       hash = (u_int32_t*)res;
-       state[0] = htonl(iv[0]);
-       state[1] = htonl(iv[1]);
-       state[2] = htonl(iv[2]);
-       state[3] = htonl(iv[3]);
-       hasher->get_hash(hasher, c, NULL);
-       hash[0] = htonl(state[0]);
-       hash[1] = htonl(state[1]);
-       hash[2] = htonl(state[2]);
-       hash[3] = htonl(state[3]);
-       hash[4] = htonl(state[4]);
-       hasher->destroy(hasher);
+       /* calculate the special (HASH_SHA1_STATE) hash*/
+       this->hasher->get_hash(this->hasher, c, res);
 }
 
 /**
@@ -232,6 +214,7 @@ void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
  */
 static void destroy(private_fips_prf_t *this)
 {
+       this->hasher->destroy(this->hasher);
        free(this->key);
        free(this);
 }
@@ -239,7 +222,7 @@ static void destroy(private_fips_prf_t *this)
 /*
  * Described in header.
  */
-fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]))
+fips_prf_t *fips_prf_create(pseudo_random_function_t algo)
 {
        private_fips_prf_t *this = malloc_thing(private_fips_prf_t);
        
@@ -250,9 +233,29 @@ fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]))
        this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
        this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
        
-       this->g = g;
-       this->b = b;
-       this->key = malloc(b);
+       switch (algo)
+       {
+               case PRF_FIPS_SHA1_160:
+               {
+                       this->g = g_sha1;
+                       this->b = 20;
+                       this->hasher = lib->crypto->create_hasher(lib->crypto,
+                                                                                                         HASH_SHA1_NOFINAL);
+                       if (this->hasher == NULL)
+                       {
+                               free(this);
+                               return NULL;
+                       }
+                       break;
+               }
+               case PRF_FIPS_DES:
+                       /* not implemented yet */
+               default:
+                       free(this);
+                       return NULL;
+       }
+       this->key = malloc(this->b);
        
-       return &(this->public);
+       return &this->public;
 }
+
similarity index 60%
rename from src/libstrongswan/crypto/prfs/fips_prf.h
rename to src/libstrongswan/plugins/fips_prf/fips_prf.h
index 283ee1f61272561a929bfe1f9b6409db2fcba8f7..3fead6b9b2d3cc047444f1046aab0674eb7158c0 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file fips_prf.h
- * 
- * @brief Interface of fips_prf_t.
- * 
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * for more details.
  */
 
+/**
+ * @defgroup fips_prf fips_prf
+ * @{ @ingroup fips_prf_p
+ */
+
 #ifndef FIPS_PRF_H_
 #define FIPS_PRF_H_
 
@@ -30,19 +28,13 @@ typedef struct fips_prf_t fips_prf_t;
 #include <crypto/hashers/hasher.h>
 
 /**
- * @brief Implementation of prf_t using the FIPS 186-2-change1 standard.
+ * Implementation of prf_t using the FIPS 186-2-change1 standard.
  *
  * FIPS defines a "General Purpose Random Number Generator" (Revised
  * Algorithm for Computing m values of x (Appendix 3.1 of FIPS 186-2)). This
  * implementation is not intended for private key generation and therefore does
  * not include the "mod q" operation (see FIPS 186-2-change1 p74).
  * The FIPS PRF is stateful; the key changes every time when bytes are acquired.
- *
- * @b Constructors:
- *  - fips_prf_create()
- *  - prf_create() using one of the FIPS algorithms
- * 
- * @ingroup prfs
  */
 struct fips_prf_t {
        
@@ -53,28 +45,15 @@ struct fips_prf_t {
 };
 
 /**
- * @brief Creates a new fips_prf_t object.
+ * Creates a new fips_prf_t object.
  * 
  * FIPS 186-2 defines G() functions used in the PRF function. It can
  * be implemented either based on SHA1 or DES.
+ * The G() function is selected using the algo parameter.
  *
- * @param b            size of b (in bytes, not bits)
- * @param g            G() function to use (e.g. g_sha1)
- * @return
- *                             - fips_prf_t object
- *                             - NULL if b invalid not supported
- * 
- * @ingroup prfs
- */
-fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]));
-
-/**
- * @brief Implementation of the G() function based on SHA1.
- *
- * @param t            initialization vector for SHA1 hasher, 20 bytes long
- * @param c            value to hash, not longer than 512 bit
- * @param res  result of G(), requries 20 bytes
+ * @param algo         specific FIPS PRF implementation, specifies G() function
+ * @return                     fips_prf_t object, NULL if not supported.
  */
-void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[]);
+fips_prf_t *fips_prf_create(pseudo_random_function_t algo);
 
-#endif /* FIPS_PRF_H_ */
+#endif /* 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
new file mode 100644 (file)
index 0000000..6825293
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "fips_prf_plugin.h"
+
+#include <library.h>
+#include "fips_prf.h"
+
+typedef struct private_fips_prf_plugin_t private_fips_prf_plugin_t;
+
+/**
+ * private data of fips_prf_plugin
+ */
+struct private_fips_prf_plugin_t {
+
+       /**
+        * public functions
+        */
+       fips_prf_plugin_t public;
+};
+
+/**
+ * Implementation of fips_prf_plugin_t.destroy
+ */
+static void destroy(private_fips_prf_plugin_t *this)
+{
+       lib->crypto->remove_prf(lib->crypto,
+                                                       (prf_constructor_t)fips_prf_create);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_fips_prf_plugin_t *this = malloc_thing(private_fips_prf_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->crypto->add_prf(lib->crypto, PRF_FIPS_SHA1_160,
+                                                (prf_constructor_t)fips_prf_create);
+       
+       return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.h
new file mode 100644 (file)
index 0000000..6816eb6
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup fips_prf_p fips_prf
+ * @ingroup plugins
+ *
+ * @defgroup fips_prf_plugin fips_prf_plugin
+ * @{ @ingroup fips_prf_p
+ */
+
+#ifndef FIPS_PRF_PLUGIN_H_
+#define FIPS_PRF_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct fips_prf_plugin_t fips_prf_plugin_t;
+
+/**
+ * Plugin implementing the fips_prf algorithm in software.
+ */
+struct fips_prf_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a fips_prf_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* FIPS_PRF_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/gmp/Makefile.am b/src/libstrongswan/plugins/gmp/Makefile.am
new file mode 100644 (file)
index 0000000..3d4065c
--- /dev/null
@@ -0,0 +1,14 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-gmp.la
+
+libstrongswan_gmp_la_SOURCES = gmp_plugin.h gmp_plugin.c \
+  gmp_diffie_hellman.c gmp_diffie_hellman.h \
+  gmp_rsa_private_key.c gmp_rsa_private_key.h \
+  gmp_rsa_public_key.c gmp_rsa_public_key.h
+libstrongswan_gmp_la_LDFLAGS = -module
+libstrongswan_gmp_la_LIBADD = -lgmp
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
new file mode 100644 (file)
index 0000000..349ec41
--- /dev/null
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 1998-2002  D. Hugh Redelmeier.
+ * Copyright (C) 1999, 2000, 2001  Henry Spencer.
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include <gmp.h>
+
+#include "gmp_diffie_hellman.h"
+
+#include <utils/randomizer.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 {
+       /**
+        * Group number as it is defined in file transform_substructure.h.
+        */
+       diffie_hellman_group_t group;
+       
+       /**
+        * Pointer to first byte of modulus (network order).
+        */
+       u_int8_t *modulus;
+       
+       /* 
+        * Length of modulus in bytes.
+        */     
+       size_t modulus_len;
+       
+       /* 
+        * Generator value.
+        */     
+       u_int16_t generator;
+};
+
+/**
+ * All supported modulus values.
+ */
+static modulus_entry_t modulus_entries[] = {
+       {MODP_768_BIT, group1_modulus, sizeof(group1_modulus), 2},
+       {MODP_1024_BIT, group2_modulus, sizeof(group2_modulus), 2},
+       {MODP_1536_BIT, group5_modulus, sizeof(group5_modulus), 2},
+       {MODP_2048_BIT, group14_modulus, sizeof(group14_modulus), 2},
+       {MODP_3072_BIT, group15_modulus, sizeof(group15_modulus), 2},
+       {MODP_4096_BIT, group16_modulus, sizeof(group16_modulus), 2},
+       {MODP_6144_BIT, group17_modulus, sizeof(group17_modulus), 2},
+       {MODP_8192_BIT, group18_modulus, sizeof(group18_modulus), 2},
+};
+
+typedef struct private_gmp_diffie_hellman_t private_gmp_diffie_hellman_t;
+
+/**
+ * Private data of an gmp_diffie_hellman_t object.
+ */
+struct private_gmp_diffie_hellman_t {
+       /**
+        * Public gmp_diffie_hellman_t interface.
+        */
+       gmp_diffie_hellman_t public;
+       
+       /**
+        * Diffie Hellman group number.
+        */
+       u_int16_t group;
+       
+       /* 
+        * Generator value.
+        */     
+       mpz_t g;
+
+       /**
+        * My private value.
+        */
+       mpz_t xa;
+       
+       /**
+        * My public value.
+        */
+       mpz_t ya;
+
+       /**
+        * Other public value.
+        */     
+       mpz_t yb;
+       
+       /**
+        * Shared secret.
+        */     
+       mpz_t zz;
+
+       /**
+        * Modulus.
+        */
+       mpz_t p;
+       
+       /**
+        * Modulus length.
+        */
+       size_t p_len;
+
+       /**
+        * True if shared secret is computed and stored in my_public_value.
+        */
+       bool computed;
+};
+
+/**
+ * Implementation of gmp_diffie_hellman_t.set_other_public_value.
+ */
+static void set_other_public_value(private_gmp_diffie_hellman_t *this, chunk_t value)
+{
+       mpz_t p_min_1;
+       
+       mpz_init(p_min_1);
+       mpz_sub_ui(p_min_1, this->p, 1);
+       
+       mpz_import(this->yb, value.len, 1, 1, 1, 0, value.ptr);
+       
+       /* 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 (mpz_cmp_ui(this->yb, 1) > 0 ||
+               mpz_cmp(this->yb, p_min_1) < 0)
+       {
+#ifdef EXTENDED_DH_TEST
+               /* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */
+               mpz_t q, one;
+               
+               mpz_init(q);
+               mpz_init(one);
+               mpz_fdiv_q_2exp(q, p_min_1, 1);
+               mpz_powm(one, this->yb, q, this->p);
+               mpz_clear(q);
+               if (mpz_cmp_ui(one, 1) == 0)
+               {
+                       mpz_powm(this->zz, this->yb, this->xa, this->p);
+                       this->computed = TRUE;
+               }
+               else
+               {
+                       DBG1("public DH value verification failed: y ^ q mod p != 1");
+               }
+               mpz_clear(one);
+#else
+               mpz_powm(this->zz, this->yb, this->xa, this->p);
+               this->computed = TRUE;
+#endif
+       }
+       else
+       {
+               DBG1("public DH value verification failed: y < 2 || y > p - 1 ");
+       }
+       mpz_clear(p_min_1);
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_other_public_value.
+ */
+static status_t get_other_public_value(private_gmp_diffie_hellman_t *this, 
+                                                                          chunk_t *value)
+{
+       if (!this->computed)
+       {
+               return FAILED;
+       }
+       value->len = this->p_len;
+    value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->yb);
+       return SUCCESS;
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_my_public_value.
+ */
+static void get_my_public_value(private_gmp_diffie_hellman_t *this,chunk_t *value)
+{
+       value->len = this->p_len;
+    value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->ya);
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_shared_secret.
+ */
+static status_t get_shared_secret(private_gmp_diffie_hellman_t *this, chunk_t *secret)
+{
+       if (!this->computed)
+       {
+               return FAILED;
+       }
+       secret->len = this->p_len;
+    secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz);
+       return SUCCESS;
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.get_dh_group.
+ */
+static diffie_hellman_group_t get_dh_group(private_gmp_diffie_hellman_t *this)
+{
+       return this->group;
+}
+
+/**
+ * Lookup the modulus in modulo table
+ */
+static status_t set_modulus(private_gmp_diffie_hellman_t *this)
+{
+       int i;
+       status_t status = NOT_FOUND;
+       
+       for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
+       {
+               if (modulus_entries[i].group == this->group)
+               {
+                       chunk_t chunk;
+                       chunk.ptr = modulus_entries[i].modulus;
+                       chunk.len = modulus_entries[i].modulus_len;
+                       mpz_import(this->p, chunk.len, 1, 1, 1, 0, chunk.ptr);
+                       this->p_len = chunk.len;
+                       mpz_set_ui(this->g, modulus_entries[i].generator);
+                       status = SUCCESS;
+                       break;
+               }
+       }
+       return status;
+}
+
+/**
+ * Implementation of gmp_diffie_hellman_t.destroy.
+ */
+static void destroy(private_gmp_diffie_hellman_t *this)
+{
+       mpz_clear(this->p);
+       mpz_clear(this->xa);
+       mpz_clear(this->ya);
+       mpz_clear(this->yb);
+       mpz_clear(this->zz);
+       mpz_clear(this->g);
+       free(this);
+}
+
+/*
+ * Described in header.
+ */
+gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group)
+{
+       private_gmp_diffie_hellman_t *this = malloc_thing(private_gmp_diffie_hellman_t);
+       randomizer_t *randomizer;
+       chunk_t random;
+       status_t status;
+
+       /* public functions */
+       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_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_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;
+       
+       /* private variables */
+       this->group = group;
+       mpz_init(this->p);
+       mpz_init(this->yb);
+       mpz_init(this->ya);
+       mpz_init(this->xa);
+       mpz_init(this->zz);
+       mpz_init(this->g);
+       
+       this->computed = FALSE;
+               
+       /* find a modulus according to group */ 
+       if (set_modulus(this) != SUCCESS)
+       {
+               destroy(this);
+               return NULL;
+       }
+       randomizer = randomizer_create();
+       status = randomizer->allocate_pseudo_random_bytes(
+                                                                                       randomizer, this->p_len, &random);
+       randomizer->destroy(randomizer);
+       if (status != SUCCESS)
+       {
+               destroy(this);
+               return NULL;
+       }
+       mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr);
+       chunk_free(&random);
+       
+       mpz_powm(this->ya, this->g, this->xa, this->p);
+       
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h
new file mode 100644 (file)
index 0000000..e2d4d68
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup gmp_diffie_hellman gmp_diffie_hellman
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_DIFFIE_HELLMAN_H_
+#define GMP_DIFFIE_HELLMAN_H_
+
+typedef struct gmp_diffie_hellman_t gmp_diffie_hellman_t;
+
+#include <library.h>
+
+/**
+ * Implementation of the Diffie-Hellman algorithm, as in RFC2631. Uses libgmp.
+ */
+struct gmp_diffie_hellman_t {
+       
+       /**
+        * Implements diffie_hellman_t interface.
+        */
+       diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new gmp_diffie_hellman_t object.
+ * 
+ * @param group                        Diffie Hellman group number to use
+ * @return                             gmp_diffie_hellman_t object, NULL if not supported
+ */
+gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group);
+
+#endif /*GMP_DIFFIE_HELLMAN_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.c b/src/libstrongswan/plugins/gmp/gmp_plugin.c
new file mode 100644 (file)
index 0000000..ffae669
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "gmp_plugin.h"
+
+#include <library.h>
+#include "gmp_diffie_hellman.h"
+#include "gmp_rsa_private_key.h"
+#include "gmp_rsa_public_key.h"
+
+typedef struct private_gmp_plugin_t private_gmp_plugin_t;
+
+/**
+ * private data of gmp_plugin
+ */
+struct private_gmp_plugin_t {
+
+       /**
+        * public functions
+        */
+       gmp_plugin_t public;
+};
+
+/**
+ * Implementation of gmp_plugin_t.gmptroy
+ */
+static void destroy(private_gmp_plugin_t *this)
+{
+       lib->crypto->remove_dh(lib->crypto,
+                                               (dh_constructor_t)gmp_diffie_hellman_create);
+       lib->creds->remove_builder(lib->creds,
+                                               (builder_constructor_t)gmp_rsa_private_key_builder);
+       lib->creds->remove_builder(lib->creds,
+                                               (builder_constructor_t)gmp_rsa_public_key_builder);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_gmp_plugin_t *this = malloc_thing(private_gmp_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->crypto->add_dh(lib->crypto, MODP_768_BIT, 
+                                               (dh_constructor_t)gmp_diffie_hellman_create);
+       lib->crypto->add_dh(lib->crypto, MODP_1024_BIT,
+                                               (dh_constructor_t)gmp_diffie_hellman_create);
+       lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, 
+                                               (dh_constructor_t)gmp_diffie_hellman_create);
+       lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, 
+                                               (dh_constructor_t)gmp_diffie_hellman_create);
+       lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, 
+                                               (dh_constructor_t)gmp_diffie_hellman_create);
+       lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, 
+                                               (dh_constructor_t)gmp_diffie_hellman_create);
+       lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, 
+                                               (dh_constructor_t)gmp_diffie_hellman_create);
+       lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, 
+                                               (dh_constructor_t)gmp_diffie_hellman_create);
+       
+       lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+                                               (builder_constructor_t)gmp_rsa_private_key_builder);
+       lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+                                               (builder_constructor_t)gmp_rsa_public_key_builder);
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.h b/src/libstrongswan/plugins/gmp/gmp_plugin.h
new file mode 100644 (file)
index 0000000..a853064
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup gmp_p gmp
+ * @ingroup plugins
+ * 
+ * @defgroup gmp_plugin gmp_plugin
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_PLUGIN_H_
+#define GMP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct gmp_plugin_t gmp_plugin_t;
+
+/**
+ * Plugin implementing asymmetric crypto algorithms using the GNU MP library.
+ */
+struct gmp_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a gmp_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* 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
new file mode 100644 (file)
index 0000000..2315df5
--- /dev/null
@@ -0,0 +1,844 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include <gmp.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "gmp_rsa_private_key.h"
+#include "gmp_rsa_public_key.h"
+
+#include <debug.h>
+#include <asn1/asn1.h>
+#include <utils/randomizer.h>
+#include <crypto/hashers/hasher.h>
+
+/**
+ *  Public exponent to use for key generation.
+ */
+#define PUBLIC_EXPONENT 0x10001
+
+typedef struct private_gmp_rsa_private_key_t private_gmp_rsa_private_key_t;
+
+/**
+ * Private data of a gmp_rsa_private_key_t object.
+ */
+struct private_gmp_rsa_private_key_t {
+       /**
+        * Public interface for this signer.
+        */
+       gmp_rsa_private_key_t public;
+       
+       /**
+        * Version of key, as encoded in PKCS#1
+        */
+       u_int version;
+       
+       /**
+        * Public modulus.
+        */
+       mpz_t n;
+       
+       /**
+        * Public exponent.
+        */
+       mpz_t e;
+       
+       /**
+        * Private prime 1.
+        */
+       mpz_t p;
+       
+       /**
+        * Private Prime 2.
+        */
+       mpz_t q;
+       
+       /**
+        * Private exponent.
+        */
+       mpz_t d;
+       
+       /**
+        * Private exponent 1.
+        */
+       mpz_t exp1;
+       
+       /**
+        * Private exponent 2.
+        */
+       mpz_t exp2;
+       
+       /**
+        * Private coefficient.
+        */
+       mpz_t coeff;
+       
+       /**
+        * Keysize in bytes.
+        */
+       size_t k;
+
+       /**
+        * 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; 
+};
+
+/* ASN.1 definition of a PKCS#1 RSA private key */
+static const asn1Object_t privkey_objects[] = {
+       { 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 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
+#define PRIV_KEY_ROOF                  16
+
+/**
+ * defined in rsa_public_key.c
+ */
+bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, identification_t **keyid,
+                                                                identification_t **keyid_info);
+
+/**
+ * Auxiliary function overwriting private key material with
+ * pseudo-random bytes before releasing it
+ */
+static void mpz_clear_randomized(mpz_t z)
+{
+       size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
+       u_int8_t *random_bytes = alloca(len);
+
+       randomizer_t *randomizer = randomizer_create();
+       
+       randomizer->get_pseudo_random_bytes(randomizer, len, random_bytes);
+
+       /* overwrite mpz_t with pseudo-random bytes before clearing it */
+       mpz_import(z, len, 1, 1, 1, 0, random_bytes);
+       mpz_clear(z);
+
+       randomizer->destroy(randomizer);
+}
+
+/**
+ * Create a mpz prime of at least prime_size
+ */
+static status_t compute_prime(private_gmp_rsa_private_key_t *this,
+                                                         size_t prime_size, mpz_t *prime)
+{
+       randomizer_t *randomizer;
+       chunk_t random_bytes;
+       status_t status;
+       
+       randomizer = randomizer_create();
+       mpz_init(*prime);
+       
+       do
+       {
+               status = randomizer->allocate_random_bytes(randomizer, prime_size,
+                                                                                                  &random_bytes);
+               if (status != SUCCESS)
+               {
+                       randomizer->destroy(randomizer);
+                       mpz_clear(*prime);
+                       return FAILED;
+               }
+               /* make sure most significant bit is set */
+               random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80;
+               
+               mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
+               mpz_nextprime (*prime, *prime);
+               chunk_free_randomized(&random_bytes);
+       }
+       /* check if it isn't too large */
+       while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size);
+       
+       randomizer->destroy(randomizer);
+       return SUCCESS;
+}
+
+/**
+ * PKCS#1 RSADP function
+ */
+static chunk_t rsadp(private_gmp_rsa_private_key_t *this, chunk_t data)
+{
+       mpz_t t1, t2;
+       chunk_t decrypted;
+       
+       mpz_init(t1);
+       mpz_init(t2);
+       
+       mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
+       
+       mpz_powm(t2, t1, this->exp1, this->p);  /* m1 = c^dP mod p */
+       mpz_powm(t1, t1, this->exp2, this->q);  /* m2 = c^dQ mod Q */
+       mpz_sub(t2, t2, t1);                                    /* h = qInv (m1 - m2) mod p */
+       mpz_mod(t2, t2, this->p);
+       mpz_mul(t2, t2, this->coeff);
+       mpz_mod(t2, t2, this->p);
+       
+       mpz_mul(t2, t2, this->q);                               /* m = m2 + h q */
+       mpz_add(t1, t1, t2);
+       
+       decrypted.len = this->k;
+       decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
+       
+       mpz_clear_randomized(t1);
+       mpz_clear_randomized(t2);
+       
+       return decrypted;
+}
+
+/**
+ * PKCS#1 RSASP1 function
+ */
+static chunk_t rsasp1(private_gmp_rsa_private_key_t *this, chunk_t data)
+{
+       return rsadp(this, data);
+}
+
+/**
+ * Implementation of gmp_rsa_private_key_t.build_emsa_pkcs1_signature.
+ */
+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)
+       {
+               return FALSE;
+       }
+
+       /* get hasher */
+       hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+       if (hasher == NULL)
+       {
+               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
+        * T = encoded_hash
+        */
+       em.len = this->k;
+       em.ptr = malloc(em.len);
+       
+       /* fill em with padding */
+       memset(em.ptr, 0xFF, em.len);
+       /* set magic bytes */
+       *(em.ptr) = 0x00;
+       *(em.ptr+1) = 0x01;
+       *(em.ptr + em.len - digestInfo.len - 1) = 0x00;
+       /* set DER-encoded hash */
+       memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
+
+       /* build signature */
+       *signature = rsasp1(this, em);
+       
+       free(digestInfo.ptr);
+       free(em.ptr);
+       
+       return TRUE;    
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static key_type_t get_type(private_gmp_rsa_private_key_t *this)
+{
+       return KEY_RSA;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+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_SHA1:
+                       return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA256:
+                       return build_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA384:
+                       return build_emsa_pkcs1_signature(this, HASH_SHA384, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA512:
+                       return build_emsa_pkcs1_signature(this, HASH_SHA512, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_MD5:
+                       return build_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
+               default:
+                       DBG1("signature scheme %N not supported in RSA",
+                                signature_scheme_names, scheme);
+                       return FALSE;
+       }
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+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;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static size_t get_keysize(private_gmp_rsa_private_key_t *this)
+{
+       return this->k;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static identification_t* get_id(private_gmp_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 gmp_rsa_private_key.destroy.
+ */
+static gmp_rsa_public_key_t* get_public_key(private_gmp_rsa_private_key_t *this)
+{
+       DBG1("creating RSA public key from private key not implemented");
+       return NULL;
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static bool belongs_to(private_gmp_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;
+}
+
+/**
+ * convert a MP integer into a DER coded ASN.1 object
+ */
+chunk_t gmp_mpz_to_asn1(const mpz_t value)
+{
+       size_t bits = mpz_sizeinbase(value, 2);  /* size in bits */
+       chunk_t n;
+
+       n.len = 1 + bits / 8;  /* size in bytes */      
+       n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value);
+
+       return asn1_wrap(ASN1_INTEGER, "m", n);
+}
+
+/**
+ * Implementation of private_key_t.get_encoding.
+ */
+static chunk_t get_encoding(private_gmp_rsa_private_key_t *this)
+{
+       return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm",
+                                        ASN1_INTEGER_0,
+                                        gmp_mpz_to_asn1(this->n),
+                                        gmp_mpz_to_asn1(this->e),
+                                        gmp_mpz_to_asn1(this->d),
+                                        gmp_mpz_to_asn1(this->p),
+                                        gmp_mpz_to_asn1(this->q),
+                                        gmp_mpz_to_asn1(this->exp1),
+                                        gmp_mpz_to_asn1(this->exp2),
+                                        gmp_mpz_to_asn1(this->coeff));
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static private_gmp_rsa_private_key_t* get_ref(private_gmp_rsa_private_key_t *this)
+{
+       ref_get(&this->ref);
+       return this;
+
+}
+
+/**
+ * Implementation of gmp_rsa_private_key.destroy.
+ */
+static void destroy(private_gmp_rsa_private_key_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               mpz_clear_randomized(this->n);
+               mpz_clear_randomized(this->e);
+               mpz_clear_randomized(this->p);
+               mpz_clear_randomized(this->q);
+               mpz_clear_randomized(this->d);
+               mpz_clear_randomized(this->exp1);
+               mpz_clear_randomized(this->exp2);
+               mpz_clear_randomized(this->coeff);
+               DESTROY_IF(this->keyid);
+               DESTROY_IF(this->keyid_info);
+               free(this);
+       }
+}
+
+/**
+ * Check the loaded key if it is valid and usable
+ */
+static status_t check(private_gmp_rsa_private_key_t *this)
+{
+       mpz_t t, u, q1;
+       status_t status = SUCCESS;
+       
+       /* 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)
+       {
+               DBG1("key shorter than 512 bits");
+               return FAILED;
+       }
+       
+       /* we picked a max modulus size to simplify buffer allocation */
+       if (this->k > 8192/8)
+       {
+               DBG1("key larger thant 8192 bits");
+               return FAILED;
+       }
+       
+       mpz_init(t);
+       mpz_init(u);
+       mpz_init(q1);
+       
+       /* check that n == p * q */
+       mpz_mul(u, this->p, this->q);
+       if (mpz_cmp(u, this->n) != 0)
+       {
+               status = FAILED;
+       }
+       
+       /* check that e divides neither p-1 nor q-1 */
+       mpz_sub_ui(t, this->p, 1);
+       mpz_mod(t, t, this->e);
+       if (mpz_cmp_ui(t, 0) == 0)
+       {
+               status = FAILED;
+       }
+       
+       mpz_sub_ui(t, this->q, 1);
+       mpz_mod(t, t, this->e);
+       if (mpz_cmp_ui(t, 0) == 0)
+       {
+               status = FAILED;
+       }
+       
+       /* 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, this->q, 1);
+       mpz_sub_ui(u, this->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, this->d, this->e);
+       mpz_mod(t, t, u);
+       if (mpz_cmp_ui(t, 1) != 0)
+       {
+               status = FAILED;
+       }
+       
+       /* check that exp1 is d mod (p-1) */
+       mpz_sub_ui(u, this->p, 1);
+       mpz_mod(t, this->d, u);
+       if (mpz_cmp(t, this->exp1) != 0)
+       {
+               status = FAILED;
+       }
+       
+       /* check that exp2 is d mod (q-1) */
+       mpz_sub_ui(u, this->q, 1);
+       mpz_mod(t, this->d, u);
+       if (mpz_cmp(t, this->exp2) != 0)
+       {
+               status = FAILED;
+       }
+       
+       /* check that coeff is (q^-1) mod p */
+       mpz_mul(t, this->coeff, this->q);
+       mpz_mod(t, t, this->p);
+       if (mpz_cmp_ui(t, 1) != 0)
+       {
+               status = FAILED;
+       }
+       
+       mpz_clear_randomized(t);
+       mpz_clear_randomized(u);
+       mpz_clear_randomized(q1);
+       if (status != SUCCESS)
+       {
+               DBG1("key integrity tests failed");
+       }
+       return status;
+}
+
+/**
+ * Internal generic constructor
+ */
+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->keyid = NULL;
+       this->keyid_info = NULL;
+       this->ref = 1;
+       
+       return this;
+}
+
+/**
+ * Generate an RSA key of specified key size
+ */
+static gmp_rsa_private_key_t *generate(size_t key_size)
+{
+       mpz_t p, q, n, e, d, exp1, exp2, coeff;
+       mpz_t m, q1, t;
+       private_gmp_rsa_private_key_t *this = gmp_rsa_private_key_create_empty();
+       
+       key_size = key_size / 8;
+       
+       /* Get values of primes p and q  */
+       if (compute_prime(this, key_size/2, &p) != SUCCESS)
+       {
+               free(this);
+               return NULL;
+       }       
+       if (compute_prime(this, key_size/2, &q) != SUCCESS)
+       {
+               mpz_clear(p);
+               free(this);
+               return NULL;
+       }
+       
+       mpz_init(t);    
+       mpz_init(n);
+       mpz_init(d);
+       mpz_init(exp1);
+       mpz_init(exp2);
+       mpz_init(coeff);
+       
+       /* Swapping Primes so p is larger then q */
+       if (mpz_cmp(p, q) < 0)
+       {
+               mpz_swap(p, q);
+       }
+       
+       mpz_mul(n, p, q);                                               /* n = p*q */
+       mpz_init_set_ui(e, PUBLIC_EXPONENT);    /* assign public exponent */
+       mpz_init_set(m, p);                                     /* m = p */
+       mpz_sub_ui(m, m, 1);                                    /* m = m -1 */
+       mpz_init_set(q1, q);                                    /* q1 = q */
+       mpz_sub_ui(q1, q1, 1);                                  /* q1 = q1 -1 */
+       mpz_gcd(t, m, q1);                                              /* t = gcd(p-1, q-1) */
+       mpz_mul(m, m, q1);                                              /* m = (p-1)*(q-1) */
+       mpz_divexact(m, m, t);                                  /* m = m / t */
+       mpz_gcd(t, m, e);                                               /* t = gcd(m, e) */
+
+       mpz_invert(d, e, m);                                    /* e has an inverse mod m */
+       if (mpz_cmp_ui(d, 0) < 0)                               /* make sure d is positive */
+       {
+               mpz_add(d, d, m);
+       }
+       mpz_sub_ui(t, p, 1);                                    /* t = p-1 */
+       mpz_mod(exp1, d, t);                                    /* exp1 = d mod p-1 */
+       mpz_sub_ui(t, q, 1);                                    /* t = q-1 */
+       mpz_mod(exp2, d, t);                                    /* exp2 = d mod q-1 */
+       
+       mpz_invert(coeff, q, p);                                /* coeff = q^-1 mod p */
+       if (mpz_cmp_ui(coeff, 0) < 0)                   /* make coeff d is positive */
+       {
+               mpz_add(coeff, coeff, p);
+       }
+
+       mpz_clear_randomized(q1);
+       mpz_clear_randomized(m);
+       mpz_clear_randomized(t);
+
+       /* apply values */
+       *(this->p) = *p;
+       *(this->q) = *q;
+       *(this->n) = *n;
+       *(this->e) = *e;
+       *(this->d) = *d;
+       *(this->exp1) = *exp1;
+       *(this->exp2) = *exp2;
+       *(this->coeff) = *coeff;
+       
+       /* set key size in bytes */
+       this->k = key_size;
+       
+       return &this->public;
+}
+
+/**
+ * load private key from a ASN1 encoded blob
+ */
+static gmp_rsa_private_key_t *load(chunk_t blob)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+       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);
+       
+       asn1_init(&ctx, blob, 0, FALSE, TRUE);
+       
+       while (objectID < PRIV_KEY_ROOF) 
+       {
+               if (!extract_object(privkey_objects, &objectID, &object, &level, &ctx))
+               {
+                       chunk_free_randomized(&blob);
+                       destroy(this);
+                       return NULL;
+               }
+               switch (objectID)
+               {
+                       case PRIV_KEY_VERSION:
+                               if (object.len > 0 && *object.ptr != 0)
+                               {
+                                       chunk_free_randomized(&blob);
+                                       destroy(this);
+                                       return NULL;
+                               }
+                               break;
+                       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->p, object.len, 1, 1, 1, 0, object.ptr);
+                               break;
+                       case PRIV_KEY_PRIME2:
+                               mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
+                               break;
+                       case PRIV_KEY_EXP1:
+                               mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr);
+                               break;
+                       case PRIV_KEY_EXP2:
+                               mpz_import(this->exp2, 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;
+               }
+               objectID++;
+       }
+       chunk_free_randomized(&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;
+}
+
+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 */
+       gmp_rsa_private_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static gmp_rsa_private_key_t *build(private_builder_t *this)
+{
+       gmp_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, ...)
+{
+       va_list args;
+       
+       if (this->key)
+       {
+               DBG1("ignoring surplus build part %N", builder_part_names, part);
+               return;
+       }
+       
+       switch (part)
+       {
+               case BUILD_BLOB_ASN1_DER:
+               {
+                       va_start(args, part);
+                       this->key = load(va_arg(args, chunk_t));
+                       va_end(args);
+                       break;
+               }               
+               case BUILD_KEY_SIZE:
+               {
+                       va_start(args, part);
+                       this->key = generate(va_arg(args, u_int));
+                       va_end(args);
+                       break;
+               }
+               default:
+                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
+                       break;
+       }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *gmp_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/gmp/gmp_rsa_private_key.h b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.h
new file mode 100644 (file)
index 0000000..6f59b2a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup gmp_rsa_private_key gmp_rsa_private_key
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_RSA_PRIVATE_KEY_H_
+#define GMP_RSA_PRIVATE_KEY_H_
+
+#include <credentials/keys/private_key.h>
+
+typedef struct gmp_rsa_private_key_t gmp_rsa_private_key_t;
+
+/**
+ * Private_key_t implementation of RSA algorithm using libgmp.
+ */
+struct gmp_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 *gmp_rsa_private_key_builder(key_type_t type);
+
+#endif /*GMP_RSA_PRIVATE_KEY_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
new file mode 100644 (file)
index 0000000..13ced71
--- /dev/null
@@ -0,0 +1,574 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+#include <gmp.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "gmp_rsa_public_key.h"
+
+#include <debug.h>
+#include <crypto/hashers/hasher.h>
+#include <asn1/asn1.h>
+#include <asn1/pem.h>
+
+/**
+ * defined in gmp_rsa_private_key.c
+ */
+extern chunk_t gmp_mpz_to_asn1(const mpz_t value);
+
+/**
+ * ASN.1 definition of a subjectPublicKeyInfo structure
+ */
+static const asn1Object_t pkinfoObjects[] = {
+       { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE,              ASN1_NONE       }, /* 0 */
+       { 1,   "algorithm",                     ASN1_EOC,                       ASN1_RAW        }, /* 1 */
+       { 1,   "subjectPublicKey",      ASN1_BIT_STRING,        ASN1_NONE       }, /* 2 */
+       { 2,     "RSAPublicKey",        ASN1_SEQUENCE,          ASN1_RAW        }, /* 3 */
+};
+#define PKINFO                                         0
+#define PKINFO_SUBJECT_PK_ALGORITHM    1
+#define PKINFO_SUBJECT_PK                      2
+#define PKINFO_gmp_rsa_public_key              3
+#define PKINFO_ROOF                                    4
+
+/* 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 */
+};
+
+#define PUB_KEY_gmp_rsa_public_key             0
+#define PUB_KEY_MODULUS                                1
+#define PUB_KEY_EXPONENT                       2
+#define PUB_KEY_ROOF                           3
+
+/* ASN.1 definition of digestInfo */
+static const asn1Object_t digestInfoObjects[] = {
+       { 0, "digestInfo",                      ASN1_SEQUENCE,          ASN1_OBJ  }, /*  0 */
+       { 1,   "digestAlgorithm",       ASN1_EOC,                       ASN1_RAW  }, /*  1 */
+       { 1,   "digest",                        ASN1_OCTET_STRING,      ASN1_BODY }, /*  2 */
+};
+
+#define DIGEST_INFO                                    0
+#define DIGEST_INFO_ALGORITHM          1
+#define DIGEST_INFO_DIGEST                     2
+#define DIGEST_INFO_ROOF                       3
+
+typedef struct private_gmp_rsa_public_key_t private_gmp_rsa_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_gmp_rsa_public_key_t {
+       /**
+        * Public interface for this signer.
+        */
+       gmp_rsa_public_key_t public;
+       
+       /**
+        * Public modulus.
+        */
+       mpz_t n;
+       
+       /**
+        * Public exponent.
+        */
+       mpz_t e;
+       
+       /**
+        * Keysize in bytes.
+        */
+       size_t k;
+       
+       /**
+        * Keyid formed as a SHA-1 hash of a publicKeyInfo object
+        */
+       identification_t *keyid_info;
+       
+       /**
+        * Keyid formed as a SHA-1 hash of a publicKey object
+        */
+       identification_t *keyid;
+       
+       /**
+        * reference counter
+        */
+       refcount_t ref;
+};
+
+/**
+ * RSAEP algorithm specified in PKCS#1.
+ */
+static chunk_t rsaep(private_gmp_rsa_public_key_t *this, chunk_t data)
+{
+       mpz_t m, c;
+       chunk_t encrypted;
+       
+       mpz_init(c);
+       mpz_init(m);
+       
+       mpz_import(m, data.len, 1, 1, 1, 0, data.ptr);
+       
+       mpz_powm(c, m, this->e, this->n);
+
+    encrypted.len = this->k;
+    encrypted.ptr = mpz_export(NULL, NULL, 1, encrypted.len, 1, 0, c);
+       
+       mpz_clear(c);
+       mpz_clear(m);   
+       
+       return encrypted;
+}
+
+/**
+ * RSAVP1 algorithm specified in PKCS#1.
+ */
+static chunk_t rsavp1(private_gmp_rsa_public_key_t *this, chunk_t data)
+{
+       return rsaep(this, data);
+}
+
+/**
+ * Verification of an EMPSA PKCS1 signature described in PKCS#1
+ */
+static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
+                                                                               hash_algorithm_t algorithm,
+                                                                               chunk_t data, chunk_t signature)
+{
+       chunk_t em_ori, em;
+       bool res = FALSE;
+       
+       /* remove any preceding 0-bytes from signature */
+       while (signature.len && *(signature.ptr) == 0x00)
+       {
+               signature.len -= 1;
+               signature.ptr++;
+       }
+       
+       if (signature.len > this->k)
+       {
+               return INVALID_ARG;
+       }
+       
+       /* unpack signature */
+       em_ori = em = rsavp1(this, signature);
+       
+       /* result should look like this:
+        * EM = 0x00 || 0x01 || PS || 0x00 || T. 
+        * PS = 0xFF padding, with length to fill em
+        * T = oid || hash
+        */
+       
+       /* check magic bytes */
+       if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
+       {
+               goto end;
+       }
+       em.ptr += 2;
+       em.len -= 2;
+       
+       /* find magic 0x00 */
+       while (em.len > 0)
+       {
+               if (*em.ptr == 0x00)
+               {
+                       /* found magic byte, stop */
+                       em.ptr++;
+                       em.len--;
+                       break;
+               }
+               else if (*em.ptr != 0xFF)
+               {
+                       /* bad padding, decryption failed ?!*/
+                       goto end;
+               }
+               em.ptr++;
+               em.len--;
+       }
+
+       if (em.len == 0)
+       {
+               /* no digestInfo found */
+               goto end;
+       }
+
+       /* parse ASN.1-based digestInfo */
+       {
+               asn1_ctx_t ctx;
+               chunk_t object;
+               u_int level;
+               int objectID = 0;
+               hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
+
+               asn1_init(&ctx, em, 0, FALSE, FALSE);
+
+               while (objectID < DIGEST_INFO_ROOF)
+               {
+                       if (!extract_object(digestInfoObjects, &objectID, &object, &level, &ctx))
+                       {
+                               goto end;
+                       }
+                       switch (objectID)
+                       {
+                               case DIGEST_INFO:
+                               {
+                                       if (em.len > object.len)
+                                       {
+                                               DBG1("digestInfo field in signature is followed by %u surplus bytes",
+                                                        em.len - object.len);
+                                               goto end;
+                                       }
+                                       break;
+                               }
+                               case DIGEST_INFO_ALGORITHM:
+                               {
+                                       int hash_oid = parse_algorithmIdentifier(object, level+1, NULL);
+
+                                       hash_algorithm = hasher_algorithm_from_oid(hash_oid);
+                                       if (hash_algorithm == HASH_UNKNOWN ||
+                                               (algorithm != HASH_UNKNOWN && hash_algorithm != algorithm))
+                                       {
+                                               DBG1("wrong hash algorithm used in signature");
+                                               goto end;
+                                       }
+                                       break;
+                               }
+                               case DIGEST_INFO_DIGEST:
+                               {
+                                       chunk_t hash;
+                                       hasher_t *hasher;
+                                       
+                                       hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+                                       if (hasher == NULL)
+                                       {
+                                               DBG1("hash algorithm %N not supported",
+                                                        hash_algorithm_names, hash_algorithm);
+                                               goto end;
+                                       }
+
+                                       if (object.len != hasher->get_hash_size(hasher))
+                                       {
+                                               DBG1("hash size in signature is %u bytes instead of %u "
+                                                        "bytes", object.len, hasher->get_hash_size(hasher));
+                                               hasher->destroy(hasher);
+                                               goto end;
+                                       }
+
+                                       /* build our own hash and compare */
+                                       hasher->allocate_hash(hasher, data, &hash);
+                                       hasher->destroy(hasher);
+                                       res = memeq(object.ptr, hash.ptr, hash.len);
+                                       free(hash.ptr);
+                                       break;
+                               }
+                               default:
+                                       break;
+                       }
+                       objectID++;
+               }
+       }
+
+end:
+       free(em_ori.ptr);
+       return res;
+}
+
+/**
+ * Implementation of public_key_t.get_type.
+ */
+static key_type_t get_type(private_gmp_rsa_public_key_t *this)
+{
+       return KEY_RSA;
+}
+
+/**
+ * Implementation of public_key_t.verify.
+ */
+static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme, 
+                                  chunk_t data, chunk_t signature)
+{
+       switch (scheme)
+       {
+               case SIGN_DEFAULT: /* default is EMSA-PKCS1 using included OID */
+                       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);
+               case SIGN_RSA_EMSA_PKCS1_SHA1:
+                       return verify_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA256:
+                       return verify_emsa_pkcs1_signature(this, HASH_SHA256, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA384:
+                       return verify_emsa_pkcs1_signature(this, HASH_SHA384, data, signature);
+               case SIGN_RSA_EMSA_PKCS1_SHA512:
+                       return verify_emsa_pkcs1_signature(this, HASH_SHA512, data, signature);
+               default:
+                       DBG1("signature scheme %N not supported in RSA",
+                                signature_scheme_names, scheme);
+                       return FALSE;
+       }
+}
+
+/**
+ * Implementation of public_key_t.get_keysize.
+ */
+static bool encrypt(private_gmp_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.get_keysize.
+ */
+static size_t get_keysize(private_gmp_rsa_public_key_t *this)
+{
+       return this->k;
+}
+
+/**
+ * Implementation of public_key_t.get_id.
+ */
+static identification_t *get_id(private_gmp_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_gmp_rsa_public_key_t *this)
+{
+       return asn1_wrap(ASN1_SEQUENCE, "mm",
+                                        gmp_mpz_to_asn1(this->n),
+                                        gmp_mpz_to_asn1(this->e));
+}
+
+/**
+ * Implementation of public_key_t.get_ref.
+ */
+static private_gmp_rsa_public_key_t* get_ref(private_gmp_rsa_public_key_t *this)
+{
+       ref_get(&this->ref);
+       return this;
+}
+
+/**
+ * Implementation of gmp_rsa_public_key.destroy.
+ */
+static void destroy(private_gmp_rsa_public_key_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               mpz_clear(this->n);
+               mpz_clear(this->e);
+               DESTROY_IF(this->keyid);
+               DESTROY_IF(this->keyid_info);
+               free(this);
+       }
+}
+
+/**
+ * Generic private constructor
+ */
+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->keyid = NULL;
+       this->keyid_info = NULL;
+       this->ref = 1;
+       
+       return this;
+}
+
+/**
+ * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info).
+ * Also used in rsa_private_key.c.
+ */
+bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, 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 == NULL)
+       {
+               DBG1("SHA1 hash algorithm not supported, unable to use RSA");
+               return FALSE;
+       }
+       publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
+                                       gmp_mpz_to_asn1(n),
+                                       gmp_mpz_to_asn1(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;
+}
+
+/**
+ * Load a public key from an ASN1 encoded blob
+ */
+static gmp_rsa_public_key_t *load(chunk_t blob)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+       private_gmp_rsa_public_key_t *this = gmp_rsa_public_key_create_empty();
+
+       mpz_init(this->n);
+       mpz_init(this->e);
+       
+       asn1_init(&ctx, blob, 0, FALSE, FALSE);
+       
+       while (objectID < PUB_KEY_ROOF) 
+       {
+               if (!extract_object(pubkeyObjects, &objectID, &object, &level, &ctx))
+               {
+                       free(blob.ptr);
+                       destroy(this);
+                       return NULL;
+               }
+               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;
+               }
+               objectID++;
+       }
+       free(blob.ptr);
+       this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+       if (!gmp_rsa_public_key_build_id(this->n, this->e,
+                                                                        &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 */
+       gmp_rsa_public_key_t *key;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static gmp_rsa_public_key_t *build(private_builder_t *this)
+{
+       gmp_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, ...)
+{
+       va_list args;
+       
+       if (this->key)
+       {
+               DBG1("ignoring surplus build part %N", builder_part_names, part);
+               return;
+       }
+       
+       switch (part)
+       {
+               case BUILD_BLOB_ASN1_DER:
+               {
+                       va_start(args, part);
+                       this->key = load(va_arg(args, chunk_t));
+                       va_end(args);
+                       break;
+               }
+               default:
+                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
+                       break;
+       }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *gmp_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/gmp/gmp_rsa_public_key.h b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.h
new file mode 100644 (file)
index 0000000..e471cd0
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup gmp_rsa_public_key gmp_rsa_public_key
+ * @{ @ingroup gmp_p
+ */
+
+#ifndef GMP_RSA_PUBLIC_KEY_H_
+#define GMP_RSA_PUBLIC_KEY_H_
+
+typedef struct gmp_rsa_public_key_t gmp_rsa_public_key_t;
+
+#include <credentials/keys/public_key.h>
+
+/**
+ * public_key_t implementation of RSA algorithm using libgmp.
+ */
+struct gmp_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 *gmp_rsa_public_key_builder(key_type_t type);
+
+#endif /*GMP_RSA_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/hmac/Makefile.am b/src/libstrongswan/plugins/hmac/Makefile.am
new file mode 100644 (file)
index 0000000..89e0638
--- /dev/null
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-hmac.la
+
+libstrongswan_hmac_la_SOURCES = hmac_plugin.h hmac_plugin.c hmac.h hmac.c \
+       hmac_prf.h hmac_prf.c hmac_signer.h hmac_signer.c
+libstrongswan_hmac_la_LDFLAGS = -module
+
similarity index 95%
rename from src/libstrongswan/crypto/hmac.c
rename to src/libstrongswan/plugins/hmac/hmac.c
index df4f90bc8cb3cc92b15d0b841db1aba85909b073..2b41bf4aa567b0abd68e8b00eaf142b16e5d9fb8 100644 (file)
@@ -1,9 +1,3 @@
-/**
- * @file hmac.c
- * 
- * @brief Implementation of hmac_t.
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -18,6 +12,8 @@
  * 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$
  */
 
 #include <string.h>
@@ -173,9 +169,7 @@ static void destroy(private_hmac_t *this)
  */
 hmac_t *hmac_create(hash_algorithm_t hash_algorithm)
 {
-       private_hmac_t *this;
-       
-       this = malloc_thing(private_hmac_t);
+       private_hmac_t *this = malloc_thing(private_hmac_t);
 
        /* set hmac_t methods */
        this->hmac.get_mac = (void (*)(hmac_t *,chunk_t,u_int8_t*))get_mac;
@@ -200,9 +194,14 @@ hmac_t *hmac_create(hash_algorithm_t hash_algorithm)
                        free(this);
                        return NULL;    
        }
-               
+       
        /* build the hasher */
-       this->h = hasher_create(hash_algorithm);
+       this->h = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+       if (this->h == NULL)
+       {
+               free(this);
+               return NULL;    
+       }
 
        /* build ipad and opad */
        this->opaded_key.ptr = malloc(this->b);
similarity index 58%
rename from src/libstrongswan/crypto/hmac.h
rename to src/libstrongswan/plugins/hmac/hmac.h
index 06b75aaf9426a411f2ea513757a741f4a00fe759..5f266e133e9a198ce9fe664523bdf6cedd300157 100644 (file)
@@ -1,11 +1,5 @@
-/**
- * @file hmac.h
- * 
- * @brief Interface of hmac_t.
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * for more details.
  */
 
+/**
+ * @defgroup hmac hmac
+ * @{ @ingroup hmac_p
+ */
+
 #ifndef HMAC_H_
 #define HMAC_H_
 
@@ -28,90 +27,67 @@ typedef struct hmac_t hmac_t;
 #include <crypto/hashers/hasher.h>
 
 /**
- * @brief Message authentication using hash functions.
+ * Message authentication using hash functions.
  *
  * This class implements the message authenticaion algorithm
  * described in RFC2104. It uses a hash function, wich must
  * be implemented as a hasher_t class.
- *
- * See http://www.faqs.org/rfcs/rfc2104.html for RFC.
- * @see        
- *                     - hasher_t
- *                     - prf_hmac_t
- *
- * @b Constructors:
- *  - hmac_create()
- *
- * @ingroup crypto
  */
 struct hmac_t {
        /**
-        * @brief Generate message authentication code.
+        * Generate message authentication code.
         * 
         * If buffer is NULL, no result is given back. A next call will
         * append the data to already supplied data. If buffer is not NULL, 
         * the mac of all apended data is calculated, returned and the
         * state of the hmac_t is reseted.
         * 
-        * @param this                  calling object
-        * @param data                  chunk of data to authenticate
-        * @param[out] buffer   pointer where the generated bytes will be written
+        * @param data          chunk of data to authenticate
+        * @param buffer        pointer where the generated bytes will be written
         */
        void (*get_mac) (hmac_t *this, chunk_t data, u_int8_t *buffer);
        
        /**
-        * @brief Generates message authentication code and 
-        * allocate space for them.
+        * Generates message authentication code and allocate space for them.
         * 
         * If chunk is NULL, no result is given back. A next call will
         * append the data to already supplied. If chunk is not NULL, 
         * the mac of all apended data is calculated, returned and the
         * state of the hmac_t reset;
         * 
-        * @param this                  calling object
-        * @param data                  chunk of data to authenticate
-        * @param[out] chunk    chunk which will hold generated bytes
+        * @param data          chunk of data to authenticate
+        * @param chunk         chunk which will hold generated bytes
         */
        void (*allocate_mac) (hmac_t *this, chunk_t data, chunk_t *chunk);
        
        /**
-        * @brief Get the block size of this hmac_t object.
+        * Get the block size of this hmac_t object.
         * 
-        * @param this                  calling object
-        * @return                              block size in bytes
+        * @return                      block size in bytes
         */
        size_t (*get_block_size) (hmac_t *this);        
        
        /**
-        * @brief Set the key for this hmac_t object.
+        * Set the key for this hmac_t object.
         * 
         * Any key length is accepted.
         * 
-        * @param this                  calling object
-        * @param key                   key to set
+        * @param key           key to set
         */
        void (*set_key) (hmac_t *this, chunk_t key);
        
        /**
-        * @brief Destroys a hmac_t object.
-        *
-        * @param this                  calling object
+        * Destroys a hmac_t object.
         */
        void (*destroy) (hmac_t *this);
 };
 
 /**
- * @brief Creates a new hmac_t object.
- * 
- * Creates a hasher_t object internally.
- * 
- * @param hash_algorithm               hash algorithm to use
- * @return
- *                                                             - hmac_t object
- *                                                             - NULL if hash algorithm is not supported
+ * Creates a new hmac_t object.
  * 
- * @ingroup transforms
+ * @param hash_algorithm       hash algorithm to use
+ * @return                                     hmac_t object, NULL if not supported
  */
 hmac_t *hmac_create(hash_algorithm_t hash_algorithm);
 
-#endif /*HMAC_H_*/
+#endif /*HMAC_H_ @}*/
diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.c b/src/libstrongswan/plugins/hmac/hmac_plugin.c
new file mode 100644 (file)
index 0000000..246fbb0
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "hmac_plugin.h"
+
+#include <library.h>
+#include "hmac_signer.h"
+#include "hmac_prf.h"
+
+typedef struct private_hmac_plugin_t private_hmac_plugin_t;
+
+/**
+ * private data of hmac_plugin
+ */
+struct private_hmac_plugin_t {
+
+       /**
+        * public functions
+        */
+       hmac_plugin_t public;
+};
+
+/**
+ * Implementation of hmac_plugin_t.hmactroy
+ */
+static void destroy(private_hmac_plugin_t *this)
+{
+       lib->crypto->remove_prf(lib->crypto,
+                                                       (prf_constructor_t)hmac_prf_create);
+       lib->crypto->remove_signer(lib->crypto,
+                                                          (signer_constructor_t)hmac_signer_create);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_hmac_plugin_t *this = malloc_thing(private_hmac_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->crypto->add_prf(lib->crypto, PRF_HMAC_MD5, 
+                                                (prf_constructor_t)hmac_prf_create);
+       lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA1, 
+                                                (prf_constructor_t)hmac_prf_create);
+       lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_256, 
+                                                (prf_constructor_t)hmac_prf_create);
+       lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_384, 
+                                                (prf_constructor_t)hmac_prf_create);
+       lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_512, 
+                                                (prf_constructor_t)hmac_prf_create);
+       
+       lib->crypto->add_signer(lib->crypto, AUTH_HMAC_MD5_96, 
+                                                       (signer_constructor_t)hmac_signer_create);
+       lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_96, 
+                                                       (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_SHA2_256_128, 
+                                                       (signer_constructor_t)hmac_signer_create);
+       lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_384_192, 
+                                                       (signer_constructor_t)hmac_signer_create);
+       lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_512_256, 
+                                                       (signer_constructor_t)hmac_signer_create);
+
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.h b/src/libstrongswan/plugins/hmac/hmac_plugin.h
new file mode 100644 (file)
index 0000000..55ba0b5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup hmac_p hmac
+ * @ingroup plugins
+ *
+ * @defgroup hmac_plugin hmac_plugin
+ * @{ @ingroup hmac_p
+ */
+
+#ifndef HMAC_PLUGIN_H_
+#define HMAC_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct hmac_plugin_t hmac_plugin_t;
+
+/**
+ * Plugin implementing HMAC algorithm to prvoide hash based PRF and signers.
+ */
+struct hmac_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a hmac_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* HMAC_PLUGIN_H_ @}*/
similarity index 82%
rename from src/libstrongswan/crypto/prfs/hmac_prf.c
rename to src/libstrongswan/plugins/hmac/hmac_prf.c
index f315f880d1bb35490690c1744c4e4031802120f1..02159bb1b8ab26619f83617b51a437876ea5c63e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file hmac_prf.c
- * 
- * @brief Implementation for hmac_prf_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 "hmac_prf.h"
 
-#include <crypto/hmac.h>
+#include "hmac.h"
 
 
 typedef struct private_hmac_prf_t private_hmac_prf_t;
@@ -96,23 +91,47 @@ static void destroy(private_hmac_prf_t *this)
 /*
  * Described in header.
  */
-hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm)
+hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo)
 {
-       private_hmac_prf_t *this = malloc_thing(private_hmac_prf_t);
+       private_hmac_prf_t *this;
+       hash_algorithm_t hash;
        
-       this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
-       this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
-       this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
-       this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
-       this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
-       this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
+       switch (algo)
+       {
+               case PRF_HMAC_SHA1:
+                       hash = HASH_SHA1;
+                       break;
+               case PRF_HMAC_MD5:
+                       hash = HASH_MD5;
+                       break;
+               case PRF_HMAC_SHA2_256:
+                       hash = HASH_SHA256;
+                       break;
+               case PRF_HMAC_SHA2_384:
+                       hash = HASH_SHA384;
+                       break;
+               case PRF_HMAC_SHA2_512:
+                       hash = HASH_SHA512;
+                       break;
+               default:
+                       return NULL;
+       }
        
-       this->hmac = hmac_create(hash_algorithm);
+       this = malloc_thing(private_hmac_prf_t);
+       this->hmac = hmac_create(hash);
        if (this->hmac == NULL)
        {
                free(this);
                return NULL;    
        }
        
+       this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
+       this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
+       this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
+       this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
+       this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
+       this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
+       
        return &(this->public);
 }
+
similarity index 62%
rename from src/libstrongswan/crypto/prfs/hmac_prf.h
rename to src/libstrongswan/plugins/hmac/hmac_prf.h
index 9b06ee3a22b35fa56d9cdf835c62231e6644d9f4..46d05f03a29ac1f968b9d65ba7031050229e74d8 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file hmac_prf.h
- * 
- * @brief Interface of hmac_prf_t.
- * 
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * for more details.
  */
 
+/**
+ * @defgroup hmac_prf hmac_prf
+ * @{ @ingroup hmac_p
+ */
+
 #ifndef PRF_HMAC_H_
 #define PRF_HMAC_H_
 
 typedef struct hmac_prf_t hmac_prf_t;
 
-#include <library.h>
 #include <crypto/prfs/prf.h>
-#include <crypto/hashers/hasher.h>
 
 /**
- * @brief Implementation of prf_t interface using the
- * HMAC algorithm.
+ * Implementation of prf_t interface using the HMAC algorithm.
  * 
  * This simply wraps a hmac_t in a prf_t. More a question of
  * interface matching.
- * 
- * @b Constructors:
- *  - hmac_prf_create()
- * 
- * @ingroup prfs
  */
 struct hmac_prf_t {
        
@@ -51,15 +41,11 @@ struct hmac_prf_t {
 };
 
 /**
- * @brief Creates a new hmac_prf_t object.
- * 
- * @param hash_algorithm       hmac's hash algorithm
- * @return
- *                                                     - hmac_prf_t object
- *                                                     - NULL if hash not supported
+ * Creates a new hmac_prf_t object.
  * 
- * @ingroup prfs
+ * @param algo         algorithm to implement
+ * @return                     hmac_prf_t object, NULL if hash not supported
  */
-hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm);
+hmac_prf_t *hmac_prf_create(pseudo_random_function_t algo);
 
-#endif /*PRF_HMAC_SHA1_H_*/
+#endif /*PRF_HMAC_SHA1_H_ @}*/
similarity index 58%
rename from src/libstrongswan/crypto/signers/hmac_signer.c
rename to src/libstrongswan/plugins/hmac/hmac_signer.c
index ad5b882a66431b3b2aa62bd94d296aa93fc82259..1b6f80d7badb2ed922cae83fdbb5fcc8c1afbedb 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file hmac_signer.c
- * 
- * @brief Implementation of hmac_signer_t.
- * 
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * WITHOUT ANY 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>
 
 #include "hmac_signer.h"
-
-#include <crypto/prfs/hmac_prf.h>
+#include "hmac.h"
 
 typedef struct private_hmac_signer_t private_hmac_signer_t;
 
@@ -41,7 +35,7 @@ struct private_hmac_signer_t {
        /**
         * Assigned hmac function.
         */
-       prf_t *hmac_prf;
+       hmac_t *hmac;
        
        /**
         * Block size (truncation of HMAC Hash)
@@ -52,69 +46,60 @@ struct private_hmac_signer_t {
 /**
  * Implementation of signer_t.get_signature.
  */
-static void get_signature(private_hmac_signer_t *this, chunk_t data, u_int8_t *buffer)
+static void get_signature(private_hmac_signer_t *this,
+                                                 chunk_t data, u_int8_t *buffer)
 {
        if (buffer == NULL)
        {       /* append mode */
-               this->hmac_prf->get_bytes(this->hmac_prf, data, NULL);
+               this->hmac->get_mac(this->hmac, data, NULL);
        }
        else
        {
-               u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
+               u_int8_t mac[this->hmac->get_block_size(this->hmac)];
                
-               this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
-               memcpy(buffer, full_mac, this->block_size);
+               this->hmac->get_mac(this->hmac, data, mac);
+               memcpy(buffer, mac, this->block_size);
        }
 }
 
 /**
  * Implementation of signer_t.allocate_signature.
  */
-static void allocate_signature (private_hmac_signer_t *this, chunk_t data, chunk_t *chunk)
+static void allocate_signature (private_hmac_signer_t *this,
+                                                               chunk_t data, chunk_t *chunk)
 {
        if (chunk == NULL)
        {       /* append mode */
-               this->hmac_prf->get_bytes(this->hmac_prf, data, NULL);
+               this->hmac->get_mac(this->hmac, data, NULL);
        }
        else
        {
-               chunk_t signature;
-               u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
+               u_int8_t mac[this->hmac->get_block_size(this->hmac)];
                
-               this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
+               this->hmac->get_mac(this->hmac, data, mac);
 
-               signature.ptr = malloc(this->block_size);
-               signature.len = this->block_size;
+               chunk->ptr = malloc(this->block_size);
+               chunk->len = this->block_size;
                
-               memcpy(signature.ptr, full_mac, this->block_size);
-
-               *chunk = signature;
+               memcpy(chunk->ptr, mac, this->block_size);
        }
 }
 
 /**
  * Implementation of signer_t.verify_signature.
  */
-static bool verify_signature(private_hmac_signer_t *this, chunk_t data, chunk_t signature)
+static bool verify_signature(private_hmac_signer_t *this,
+                                                        chunk_t data, chunk_t signature)
 {
-       u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
+       u_int8_t mac[this->hmac->get_block_size(this->hmac)];
        
-       this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
+       this->hmac->get_mac(this->hmac, data, mac);
        
        if (signature.len != this->block_size)
        {
                return FALSE;
        }
-       
-       /* compare mac aka signature :-) */
-       if (memcmp(signature.ptr, full_mac, this->block_size) == 0)
-       {
-               return TRUE;
-       }
-       else
-       {
-               return FALSE;
-       }
+       return memeq(signature.ptr, mac, this->block_size);
 }
 
 /**
@@ -122,8 +107,7 @@ static bool verify_signature(private_hmac_signer_t *this, chunk_t data, chunk_t
  */
 static size_t get_key_size(private_hmac_signer_t *this)
 {
-       /* for HMAC signer, IKEv2 uses block size as key size */
-       return this->hmac_prf->get_block_size(this->hmac_prf);
+       return this->hmac->get_block_size(this->hmac);
 }
 
 /**
@@ -139,7 +123,7 @@ static size_t get_block_size(private_hmac_signer_t *this)
  */
 static void set_key(private_hmac_signer_t *this, chunk_t key)
 {
-       this->hmac_prf->set_key(this->hmac_prf, key);
+       this->hmac->set_key(this->hmac, key);
 }
 
 /**
@@ -147,7 +131,7 @@ static void set_key(private_hmac_signer_t *this, chunk_t key)
  */
 static status_t destroy(private_hmac_signer_t *this)
 {
-       this->hmac_prf->destroy(this->hmac_prf);
+       this->hmac->destroy(this->hmac);
        free(this);
        return SUCCESS;
 }
@@ -155,22 +139,51 @@ static status_t destroy(private_hmac_signer_t *this)
 /*
  * Described in header
  */
-hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_size)
+hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo)
 {
-       size_t hmac_block_size;
-       private_hmac_signer_t *this = malloc_thing(private_hmac_signer_t);
-
-       this->hmac_prf = (prf_t *) hmac_prf_create(hash_algoritm);
-       if (this->hmac_prf == NULL)
+       private_hmac_signer_t *this;
+       size_t trunc;
+       hash_algorithm_t hash;
+       
+       switch (algo)
+       {
+               case AUTH_HMAC_SHA1_96:
+                       hash = HASH_SHA1;
+                       trunc = 12;
+                       break;
+               case AUTH_HMAC_SHA1_128:
+                       hash = HASH_SHA1;
+                       trunc = 16;
+                       break;
+               case AUTH_HMAC_MD5_96:
+                       hash = HASH_MD5;
+                       trunc = 12;
+                       break;
+               case AUTH_HMAC_SHA2_256_128:
+                       hash = HASH_SHA256;
+                       trunc = 16;
+                       break;
+               case AUTH_HMAC_SHA2_384_192:
+                       hash = HASH_SHA384;
+                       trunc = 24;
+                       break;
+               case AUTH_HMAC_SHA2_512_256:
+                       hash = HASH_SHA512;
+                       trunc = 32;
+                       break;
+               default:
+                       return NULL;
+       }
+       
+       this = malloc_thing(private_hmac_signer_t);
+       this->hmac = hmac_create(hash);
+       if (this->hmac == NULL)
        {
-               /* algorithm not supported */
                free(this);
                return NULL;
        }
-       
        /* prevent invalid truncation */
-       hmac_block_size = this->hmac_prf->get_block_size(this->hmac_prf);
-       this->block_size = min(block_size, hmac_block_size);
+       this->block_size = min(trunc, this->hmac->get_block_size(this->hmac));
        
        /* interface functions */
        this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
@@ -183,3 +196,4 @@ hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_s
        
        return &(this->public);
 }
+
similarity index 63%
rename from src/libstrongswan/crypto/signers/hmac_signer.h
rename to src/libstrongswan/plugins/hmac/hmac_signer.h
index 2449069bdba47c2850887573d49054a07447305d..969f482e73e3c34c9c026e37e47f71b274785bfa 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file hmac_signer.h
- * 
- * @brief Interface of hmac_signer_t.
- * 
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * for more details.
  */
 
+/**
+ * @defgroup hmac_signer hmac_signer
+ * @{ @ingroup hmac_p
+ */
+
 #ifndef HMAC_SIGNER_H_
 #define HMAC_SIGNER_H_
 
 typedef struct hmac_signer_t hmac_signer_t;
 
 #include <crypto/signers/signer.h>
-#include <crypto/hashers/hasher.h>
 
 /**
- * @brief Implementation of signer_t interface using HMAC.
+ * Implementation of signer_t interface using HMAC.
  *
- * HMAC uses a standard hash function implemented in a hasher_t to build
- * a MAC.
- *
- * @ingroup signers
+ * HMAC uses a standard hash function implemented in a hasher_t to build a MAC.
  */
 struct hmac_signer_t {
        
@@ -46,23 +40,16 @@ struct hmac_signer_t {
 };
 
 /**
- * @brief Creates a new hmac_signer_t.
+ * Creates a new hmac_signer_t.
  *
  * HMAC signatures are often truncated to shorten them to a more usable, but
  * still secure enough length.
  * Block size must be equal or smaller then the hash algorithms
  * hash.
  *
- * @param hash_algoritm                Hash algorithm to use with signer
- * @param block_size           Size of resulting signature (truncated to block_size)
- * @return                                     
- *                                                     - hmac_signer_t
- *                                                     - NULL if hash algorithm not supported
- * 
- * @ingroup signers
+ * @param algo         algorithm to implement
+ * @return                     hmac_signer_t, NULL if  not supported
  */
-hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm,
-                                                                 size_t block_size);
-
+hmac_signer_t *hmac_signer_create(integrity_algorithm_t algo);
 
-#endif /*HMAC_SIGNER_H_*/
+#endif /*HMAC_SIGNER_H_ @}*/
diff --git a/src/libstrongswan/plugins/ldap/Makefile.am b/src/libstrongswan/plugins/ldap/Makefile.am
new file mode 100644 (file)
index 0000000..ac6b4be
--- /dev/null
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-ldap.la
+
+libstrongswan_ldap_la_SOURCES = ldap_plugin.h ldap_plugin.c ldap_fetcher.h ldap_fetcher.c
+libstrongswan_ldap_la_LDFLAGS = -module
+libstrongswan_ldap_la_LIBADD  = -lldap -llber
+
diff --git a/src/libstrongswan/plugins/ldap/ldap_fetcher.c b/src/libstrongswan/plugins/ldap/ldap_fetcher.c
new file mode 100644 (file)
index 0000000..501927d
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 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.
+ *
+ * $Id$
+ */
+
+#ifndef LDAP_DEPRECATED
+#define LDAP_DEPRECATED        1
+#endif /* LDAP_DEPRECATED */
+#include <ldap.h>
+
+#include <errno.h>
+
+#include <library.h>
+#include <debug.h>
+
+#include "ldap_fetcher.h"
+
+#define DEFAULT_TIMEOUT 10
+
+typedef struct private_ldap_fetcher_t private_ldap_fetcher_t;
+
+/**
+ * Private Data of a ldap_fetcher_t object.
+ */
+struct private_ldap_fetcher_t {
+       /**
+        * Public data
+        */
+       ldap_fetcher_t public;
+       
+       /**
+        * timeout to use for fetches
+        */
+       u_int timeout;
+};
+
+/**
+ * Parses the result returned by an ldap query
+ */
+static bool parse(LDAP *ldap, LDAPMessage *result, chunk_t *response)
+{
+       LDAPMessage *entry = ldap_first_entry(ldap, result);
+       bool success = FALSE;
+
+       if (entry)
+       {
+               BerElement *ber = NULL;
+               char *attr;
+
+               attr = ldap_first_attribute(ldap, entry, &ber);
+               if (attr)
+               {
+                       struct berval **values = ldap_get_values_len(ldap, entry, attr);
+
+                       if (values)
+                       {
+                               if (values[0])
+                               {
+                                       *response = chunk_alloc(values[0]->bv_len);
+                                       memcpy(response->ptr, values[0]->bv_val, response->len);
+                                       success = TRUE;
+                               }
+                               else
+                               {
+                                       DBG1("LDAP response contains no values");
+                               }
+                               ldap_value_free_len(values);
+                       }
+                       else
+                       {
+                               DBG1("getting LDAP values failed: %s", 
+                                        ldap_err2string(ldap_result2error(ldap, entry, 0)));
+                       }
+                       ldap_memfree(attr);
+               }
+               else
+               {
+                       DBG1("finding LDAP attributes failed: %s",
+                                ldap_err2string(ldap_result2error(ldap, entry, 0)));
+               }
+               ber_free(ber, 0);
+       }
+       else
+       {
+               DBG1("finding first LDAP entry failed: %s",
+                        ldap_err2string(ldap_result2error(ldap, entry, 0)));
+       }
+       return success;
+}
+
+
+static status_t fetch(private_ldap_fetcher_t *this, char *url,
+                                         chunk_t *result, va_list args)
+{
+       LDAP *ldap;
+       LDAPURLDesc *lurl;
+       LDAPMessage *msg;
+       int res;
+       int ldap_version = LDAP_VERSION3;
+       struct timeval timeout;
+       status_t status = FAILED;
+       
+       if (!strneq(url, "ldap", 4))
+       {
+               return NOT_SUPPORTED;
+       }
+       if (ldap_url_parse(url, &lurl) != LDAP_SUCCESS)
+       {
+               return NOT_SUPPORTED;
+       }
+       ldap = ldap_init(lurl->lud_host, lurl->lud_port);
+       if (ldap == NULL)
+       {
+               DBG1("LDAP initialization failed: %s", strerror(errno));
+               ldap_free_urldesc(lurl);
+               return FAILED;
+       }
+       
+       timeout.tv_sec = this->timeout;
+       timeout.tv_usec = 0;
+
+       ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
+       ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
+
+       DBG1("sending LDAP request to '%s'...", url);
+
+       res = ldap_simple_bind_s(ldap, NULL, NULL);
+       if (res == LDAP_SUCCESS)
+       {
+               res = ldap_search_st(ldap, lurl->lud_dn, lurl->lud_scope,
+                                                        lurl->lud_filter, lurl->lud_attrs,
+                                                        0, &timeout, &msg);
+
+               if (res == LDAP_SUCCESS)
+               {
+                       if (parse(ldap, msg, result))
+                       {
+                               status = SUCCESS;
+                       }
+                       ldap_msgfree(msg);
+               }
+               else
+               {
+                       DBG1("LDAP search failed: %s", ldap_err2string(res));
+               }
+       }
+       else
+       {
+               DBG1("LDAP bind to '%s' failed: %s", url, ldap_err2string(res));
+       }
+       ldap_unbind_s(ldap);
+       ldap_free_urldesc(lurl);
+       return status;
+}
+
+
+/**
+ * Implementation of fetcher_t.set_option.
+ */
+static bool set_option(private_ldap_fetcher_t *this, fetcher_option_t option, ...)
+{
+       va_list args;
+       
+       va_start(args, option);
+       switch (option)
+       {
+               case FETCH_TIMEOUT:
+               {
+                       this->timeout = va_arg(args, u_int);
+                       return TRUE;
+               }
+               default:
+                       return FALSE;
+       }
+}
+
+/**
+ * Implements ldap_fetcher_t.destroy
+ */
+static void destroy(private_ldap_fetcher_t *this)
+{
+       free(this);
+}
+
+/*
+ * Described in header.
+ */
+ldap_fetcher_t *ldap_fetcher_create()
+{
+       private_ldap_fetcher_t *this = malloc_thing(private_ldap_fetcher_t);
+
+       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;
+       
+       this->timeout = DEFAULT_TIMEOUT;
+       
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/ldap/ldap_fetcher.h b/src/libstrongswan/plugins/ldap/ldap_fetcher.h
new file mode 100644 (file)
index 0000000..bde60c7
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ldap_fetcher ldap_fetcher
+ * @{ @ingroup ldap_p
+ */
+
+#ifndef LDAP_FETCHER_H_
+#define LDAP_FETCHER_H_
+
+typedef struct ldap_fetcher_t ldap_fetcher_t;
+
+/**
+ * Fetcher implementation using OpenLDAP.
+ */
+struct ldap_fetcher_t {
+
+       /**
+        * Implements fetcher interface
+        */
+       fetcher_t interface;
+};
+
+/**
+ * Create a ldap_fetcher instance.
+ */
+ldap_fetcher_t *ldap_fetcher_create();
+
+#endif /* LDAP_FETCHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/ldap/ldap_plugin.c b/src/libstrongswan/plugins/ldap/ldap_plugin.c
new file mode 100644 (file)
index 0000000..f063ef7
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "ldap_plugin.h"
+
+#include <library.h>
+#include "ldap_fetcher.h"
+
+typedef struct private_ldap_plugin_t private_ldap_plugin_t;
+
+/**
+ * private data of ldap_plugin
+ */
+struct private_ldap_plugin_t {
+
+       /**
+        * public functions
+        */
+       ldap_plugin_t public;
+};
+
+/**
+ * Implementation of ldap_plugin_t.destroy
+ */
+static void destroy(private_ldap_plugin_t *this)
+{
+       lib->fetcher->remove_fetcher(lib->fetcher, 
+                                                                (fetcher_constructor_t)ldap_fetcher_create);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_ldap_plugin_t *this = malloc_thing(private_ldap_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+       lib->fetcher->add_fetcher(lib->fetcher,
+                                               (fetcher_constructor_t)ldap_fetcher_create, "ldap://");
+       lib->fetcher->add_fetcher(lib->fetcher,
+                                               (fetcher_constructor_t)ldap_fetcher_create, "ldaps://");
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/ldap/ldap_plugin.h b/src/libstrongswan/plugins/ldap/ldap_plugin.h
new file mode 100644 (file)
index 0000000..7b2bb32
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ldap_p ldap
+ * @ingroup plugins
+ *
+ * @defgroup ldap_plugin ldap_plugin
+ * @{ @ingroup ldap_p
+ */
+
+#ifndef LDAP_PLUGIN_H_
+#define LDAP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct ldap_plugin_t ldap_plugin_t;
+
+/**
+ * Plugin implementing LDAP fetcher using OpenLDAP.
+ */
+struct ldap_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a ldap_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* LDAP_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/md5/Makefile.am b/src/libstrongswan/plugins/md5/Makefile.am
new file mode 100644 (file)
index 0000000..0a9c5cb
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-md5.la
+
+libstrongswan_md5_la_SOURCES = md5_plugin.h md5_plugin.c md5_hasher.c md5_hasher.h
+libstrongswan_md5_la_LDFLAGS = -module
+
similarity index 95%
rename from src/libstrongswan/crypto/hashers/md5_hasher.c
rename to src/libstrongswan/plugins/md5/md5_hasher.c
index d4dde3693a9a95125d8b0adf18dcd3048bc5831e..8b24f8cb2ac963844e5b24818fc33eff0cf0a048 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file md5_hasher.c
- * 
- * @brief Implementation of md5_hasher_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -24,6 +17,8 @@
  * WITHOUT ANY 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>
@@ -363,19 +358,6 @@ static void reset(private_md5_hasher_t *this)
        this->count[1] = 0;
 }
 
-/**
- * Implementation of hasher_t.get_state
- */
-static chunk_t get_state(private_md5_hasher_t *this)
-{
-       chunk_t chunk;
-       
-       chunk.ptr = (u_char*)&this->state[0];
-       chunk.len = sizeof(this->state);
-       
-       return chunk;
-}
-
 /**
  * Implementation of hasher_t.destroy.
  */
@@ -387,15 +369,20 @@ static void destroy(private_md5_hasher_t *this)
 /*
  * Described in header.
  */
-md5_hasher_t *md5_hasher_create(void)
+md5_hasher_t *md5_hasher_create(hash_algorithm_t algo)
 {
-       private_md5_hasher_t *this = malloc_thing(private_md5_hasher_t);
-
+       private_md5_hasher_t *this;
+       
+       if (algo != HASH_MD5)
+       {
+               return NULL;
+       }
+       this = malloc_thing(private_md5_hasher_t);
+       
        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.get_state = (chunk_t (*) (hasher_t*))get_state;
        this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
        
        /* initialize */
similarity index 65%
rename from src/libstrongswan/crypto/hashers/md5_hasher.h
rename to src/libstrongswan/plugins/md5/md5_hasher.h
index 715f11663f19dee738fe7d7596f1b3d3a6484d5e..d4a0417ab2ceb40739b68c22f0072e4e3058dce2 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file md5_hasher.h
- * 
- * @brief Interface for md5_hasher_t.
- * 
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * for more details.
  */
 
+/**
+ * @defgroup md5_hasher md5_hasher
+ * @{ @ingroup md5_p
+ */
+
 #ifndef MD5_HASHER_H_
 #define MD5_HASHER_H_
 
@@ -29,16 +27,7 @@ typedef struct md5_hasher_t md5_hasher_t;
 #include <crypto/hashers/hasher.h>
 
 /**
- * @brief Implementation of hasher_t interface using the
- * MD5 algorithm.
- *
- * @b Constructors:
- * - hasher_create() using HASH_MD5 as algorithm
- * - md5_hasher_create()
- *
- * @see hasher_t
- *
- * @ingroup hashers
+ * Implementation of hasher_t interface using the MD5 algorithm.
  */
 struct md5_hasher_t {
        
@@ -49,12 +38,11 @@ struct md5_hasher_t {
 };
 
 /**
- * @brief Creates a new md5_hasher_t.
- * 
- * @return     md5_hasher_t object
+ * Creates a new md5_hasher_t.
  * 
- * @ingroup hashers
+ * @param algo         hash algorithm, must be HASH_MD5
+ * @return                     md5_hasher_t object, NULL if not supported
  */
-md5_hasher_t *md5_hasher_create(void);
+md5_hasher_t *md5_hasher_create(hash_algorithm_t algo);
 
-#endif /*MD5_HASHER_H_*/
+#endif /*MD5_HASHER_H_@}*/
diff --git a/src/libstrongswan/plugins/md5/md5_plugin.c b/src/libstrongswan/plugins/md5/md5_plugin.c
new file mode 100644 (file)
index 0000000..94ff04d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "md5_plugin.h"
+
+#include <library.h>
+#include "md5_hasher.h"
+
+typedef struct private_md5_plugin_t private_md5_plugin_t;
+
+/**
+ * private data of md5_plugin
+ */
+struct private_md5_plugin_t {
+
+       /**
+        * public functions
+        */
+       md5_plugin_t public;
+};
+
+/**
+ * Implementation of md5_plugin_t.destroy
+ */
+static void destroy(private_md5_plugin_t *this)
+{
+       lib->crypto->remove_hasher(lib->crypto,
+                                                          (hasher_constructor_t)md5_hasher_create);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_md5_plugin_t *this = malloc_thing(private_md5_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->crypto->add_hasher(lib->crypto, HASH_MD5,
+                                                       (hasher_constructor_t)md5_hasher_create);
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/md5/md5_plugin.h b/src/libstrongswan/plugins/md5/md5_plugin.h
new file mode 100644 (file)
index 0000000..e8e8dd5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup md5_p md5
+ * @ingroup plugins
+ *
+ * @defgroup md5_plugin md5_plugin
+ * @{ @ingroup md5_p
+ */
+
+#ifndef MD5_PLUGIN_H_
+#define MD5_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct md5_plugin_t md5_plugin_t;
+
+/**
+ * Plugin implementing the MD5 hash algorithm in software.
+ */
+struct md5_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a md5_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* MD5_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/mysql/Makefile.am b/src/libstrongswan/plugins/mysql/Makefile.am
new file mode 100644 (file)
index 0000000..ec94b8f
--- /dev/null
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-mysql.la
+
+libstrongswan_mysql_la_SOURCES = mysql_plugin.h mysql_plugin.c  \
+       mysql_database.h mysql_database.c
+libstrongswan_mysql_la_LDFLAGS = -module
+libstrongswan_mysql_la_LIBADD = -lmysqlclient_r
+
diff --git a/src/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c
new file mode 100644 (file)
index 0000000..0fd3d53
--- /dev/null
@@ -0,0 +1,686 @@
+/*
+ * 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$
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <pthread.h>
+#include <mysql/mysql.h>
+
+#include "mysql_database.h"
+
+#include <debug.h>
+#include <utils/mutex.h>
+#include <utils/linked_list.h>
+
+
+typedef struct private_mysql_database_t private_mysql_database_t;
+
+/**
+ * private data of mysql_database
+ */
+struct private_mysql_database_t {
+
+       /**
+        * public functions
+        */
+       mysql_database_t public;
+       
+       /**
+        * connection pool, contains conn_t
+        */
+       linked_list_t *pool;
+       
+       /**
+        * mutex to lock pool
+        */
+       mutex_t *mutex;
+       
+       /**
+        * hostname to connect to
+        */
+       char *host;
+       
+       /**
+        * username to use
+        */
+       char *username;
+       
+       /**
+        * password
+        */
+       char *password;
+       
+       /**
+        * database name
+        */
+       char *database;
+       
+       /**
+        * tcp port
+        */
+       int port;
+};
+
+typedef struct conn_t conn_t;
+
+/**
+ * connection pool entry
+ */
+struct conn_t {
+       
+       /**
+        * MySQL database connection
+        */
+       MYSQL *mysql;
+       
+       /**
+        * connection in use?
+        */
+       bool in_use;
+};
+
+/**
+ * Release a mysql connection
+ */
+static void conn_release(conn_t *conn)
+{
+       conn->in_use = FALSE;
+}
+/**
+ * thread specific initialization flag
+ */
+pthread_key_t initialized;
+
+/**
+ * Initialize a thread for mysql usage
+ */
+static void thread_initialize()
+{
+       if (pthread_getspecific(initialized) == NULL)
+       {
+               pthread_setspecific(initialized, (void*)TRUE);
+               mysql_thread_init();
+       }
+}
+
+/**
+ * mysql library initialization function
+ */
+bool mysql_database_init()
+{
+       if (mysql_library_init(0, NULL, NULL))
+       {
+               return FALSE;
+       }
+       if (pthread_key_create(&initialized, (void*)mysql_thread_end))
+       {
+               mysql_library_end();
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/**
+ * mysql library cleanup function
+ */
+void mysql_database_deinit()
+{
+       pthread_key_delete(initialized);
+       mysql_thread_end();
+       /* mysql_library_end(); would be the clean way, however, it hangs... */
+}
+
+/**
+ * Destroy a mysql connection
+ */
+static void conn_destroy(conn_t *this)
+{
+       mysql_close(this->mysql);
+       free(this);
+}
+
+/**
+ * Acquire/Reuse a mysql connection
+ */
+static conn_t *conn_get(private_mysql_database_t *this)
+{
+       conn_t *current, *found = NULL;
+       enumerator_t *enumerator;
+       
+       thread_initialize();
+       
+       while (TRUE)
+       {
+               this->mutex->lock(this->mutex);
+               enumerator = this->pool->create_enumerator(this->pool);
+               while (enumerator->enumerate(enumerator, &current))
+               {
+                       if (!current->in_use)
+                       {
+                               found = current;
+                               found->in_use = TRUE;
+                               break;
+                       }
+               }
+               enumerator->destroy(enumerator);
+               this->mutex->unlock(this->mutex);
+               if (found)
+               {       /* check connection if found, release if ping fails */
+                       if (mysql_ping(found->mysql) == 0)
+                       {
+                               break;
+                       }
+                       this->mutex->lock(this->mutex);
+                       this->pool->remove(this->pool, found, NULL);
+                       this->mutex->unlock(this->mutex);
+                       conn_destroy(found);
+                       found = NULL;
+                       continue;
+               }
+               break;
+       }
+       if (found == NULL)
+       {
+               found = malloc_thing(conn_t);
+               found->in_use = TRUE;
+               found->mysql = mysql_init(NULL);
+               if (!mysql_real_connect(found->mysql, this->host, this->username,
+                                                               this->password, this->database, this->port,
+                                                               NULL, 0))
+               {
+                       DBG1("connecting to mysql://%s:***@%s:%d/%s failed: %s",
+                                this->username, this->host, this->port, this->database,
+                                mysql_error(found->mysql));
+                       conn_destroy(found);
+                       found = NULL;
+               }
+               else
+               {
+                       this->mutex->lock(this->mutex);
+                       this->pool->insert_last(this->pool, found);
+                       DBG1("increased MySQL connection pool size to %d",
+                                this->pool->get_count(this->pool));
+                       this->mutex->unlock(this->mutex);
+               }
+       }
+       return found;
+}
+
+/**
+ * Create and run a MySQL stmt using a sql string and args
+ */
+static MYSQL_STMT* run(MYSQL *mysql, char *sql, va_list *args)
+{
+       MYSQL_STMT *stmt;
+       int params;
+       
+       stmt = mysql_stmt_init(mysql);
+       if (stmt == NULL)
+       {
+       DBG1("creating MySQL statement failed: %s", mysql_error(mysql));
+               return NULL;
+       }
+       if (mysql_stmt_prepare(stmt, sql, strlen(sql)))
+       {
+       DBG1("preparing MySQL statement failed: %s", mysql_stmt_error(stmt));
+       mysql_stmt_close(stmt);
+       return NULL;
+       }
+       params = mysql_stmt_param_count(stmt);
+       if (params > 0)
+       {
+               int i;
+               MYSQL_BIND *bind;
+       
+               bind = alloca(sizeof(MYSQL_BIND) * params);
+               memset(bind, 0, sizeof(MYSQL_BIND) * params);
+               
+               for (i = 0; i < params; i++)
+               {
+                       switch (va_arg(*args, db_type_t))
+                       {
+                               case DB_INT:
+                               {
+                                       bind[i].buffer_type = MYSQL_TYPE_LONG;
+                                       bind[i].buffer = (char*)alloca(sizeof(int));
+                                       *(int*)bind[i].buffer = va_arg(*args, int);
+                                       bind[i].buffer_length = sizeof(int);
+                                       break;
+                               }
+                               case DB_UINT:
+                               {
+                                       bind[i].buffer_type = MYSQL_TYPE_LONG;
+                                       bind[i].buffer = (char*)alloca(sizeof(u_int));
+                                       *(u_int*)bind[i].buffer = va_arg(*args, u_int);
+                                       bind[i].buffer_length = sizeof(u_int);
+                                       bind[i].is_unsigned = TRUE;
+                                       break;
+                               }
+                               case DB_TEXT:
+                               {
+                                       bind[i].buffer_type = MYSQL_TYPE_STRING;;
+                                       bind[i].buffer = va_arg(*args, char*);
+                                       bind[i].buffer_length = strlen(bind[i].buffer);
+                                       break;
+                               }
+                               case DB_BLOB:
+                               {       
+                                       chunk_t chunk = va_arg(*args, chunk_t);
+                                       bind[i].buffer_type = MYSQL_TYPE_BLOB;
+                                       bind[i].buffer = chunk.ptr;
+                                       bind[i].buffer_length = chunk.len;
+                                       break;
+                               }
+                               case DB_DOUBLE:
+                               {
+                                       bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
+                                       bind[i].buffer = (char*)alloca(sizeof(double));
+                                       *(double*)bind[i].buffer = va_arg(*args, double);
+                                       bind[i].buffer_length = sizeof(double);
+                                       break;
+                               }
+                       case DB_NULL:
+                               {
+                                       bind[i].buffer_type = MYSQL_TYPE_NULL;
+                                       break;
+                               }
+                               default:
+                               DBG1("invalid data type supplied");
+                               mysql_stmt_close(stmt);
+                               return NULL;
+                       }
+               }
+               if (mysql_stmt_bind_param(stmt, bind))
+               {
+               DBG1("binding MySQL param failed: %s", mysql_stmt_error(stmt));
+               mysql_stmt_close(stmt);
+                       return NULL;
+               }
+       }
+       if (mysql_stmt_execute(stmt))
+       {
+       DBG1("executing MySQL statement failed: %s", mysql_stmt_error(stmt));
+       mysql_stmt_close(stmt);
+               return NULL;
+       }
+       return stmt;
+}
+
+typedef struct {
+       /** implements enumerator_t */
+       enumerator_t public;
+       /** associated MySQL statement */
+       MYSQL_STMT *stmt;
+       /** result bindings */
+       MYSQL_BIND *bind;
+       /** pooled connection handle */
+       conn_t *conn;
+       /** value for INT, UINT, double */
+       union {
+               void *p_void;;
+               int *p_int;
+               u_int *p_uint;
+               double *p_double;
+       } val;
+       /* length for TEXT and BLOB */
+       unsigned long *length;
+} mysql_enumerator_t;
+
+/**
+ * create a mysql enumerator
+ */
+static void mysql_enumerator_destroy(mysql_enumerator_t *this)
+{
+       int columns, i;
+       
+       columns = mysql_stmt_field_count(this->stmt);
+       
+       for (i = 0; i < columns; i++)
+       {
+               switch (this->bind[i].buffer_type)
+               {
+                       case MYSQL_TYPE_STRING:
+                       case MYSQL_TYPE_BLOB:
+                       {
+                               free(this->bind[i].buffer);
+                               break;
+                       }
+                       default:
+                               break;
+               }
+       }
+       mysql_stmt_close(this->stmt);
+       conn_release(this->conn);
+       free(this->bind);
+       free(this->val.p_void);
+       free(this->length);
+       free(this);
+}
+
+/**
+ * Implementation of database.query().enumerate
+ */
+static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...)
+{
+       int i, columns;
+       va_list args;
+       
+       columns = mysql_stmt_field_count(this->stmt);
+       
+       /* free/reset data set of previous call */
+       for (i = 0; i < columns; i++)
+       {
+               switch (this->bind[i].buffer_type)
+               {
+                       case MYSQL_TYPE_STRING:
+                       case MYSQL_TYPE_BLOB:
+                       {
+                               free(this->bind[i].buffer);
+                               this->bind[i].buffer = NULL;
+                               this->bind[i].buffer_length = 0;
+                               this->bind[i].length = &this->length[i];
+                               this->length[i] = 0;
+                               break;
+                       }
+                       default:
+                               break;
+               }
+       }
+
+       switch (mysql_stmt_fetch(this->stmt))
+       {
+               case 0:
+               case MYSQL_DATA_TRUNCATED:
+                       break;
+               case MYSQL_NO_DATA:
+                       return FALSE;
+               default:
+                       DBG1("fetching MySQL row failed: %s", mysql_stmt_error(this->stmt));
+                       return FALSE;
+       }
+       
+       va_start(args, this);
+       for (i = 0; i < columns; i++)
+       {
+               switch (this->bind[i].buffer_type)
+               {
+                       case MYSQL_TYPE_LONG:
+                       {
+                               if (this->bind[i].is_unsigned)
+                               {
+                                       u_int *value = va_arg(args, u_int*);
+                                       *value = this->val.p_uint[i];
+                               }
+                               else
+                               {
+                                       int *value = va_arg(args, int*);
+                                       *value = this->val.p_int[i];
+                               }
+                               break;
+                       }
+                       case MYSQL_TYPE_STRING:
+                       {
+                               char **value = va_arg(args, char**);
+                               this->bind[i].buffer = malloc(this->length[i]+1);
+                               this->bind[i].buffer_length = this->length[i];
+                               *value = this->bind[i].buffer;
+                               mysql_stmt_fetch_column(this->stmt, &this->bind[i], i, 0);
+                               ((char*)this->bind[i].buffer)[this->length[i]] = '\0';
+                               break;
+                       }
+                       case MYSQL_TYPE_BLOB:
+                       {
+                               chunk_t *value = va_arg(args, chunk_t*);
+                               this->bind[i].buffer = malloc(this->length[i]);
+                               this->bind[i].buffer_length = this->length[i];
+                               value->ptr = this->bind[i].buffer;
+                               value->len = this->length[i];
+                               mysql_stmt_fetch_column(this->stmt, &this->bind[i], i, 0);
+                               break;
+                       }
+                       case MYSQL_TYPE_DOUBLE:
+                       {
+                               double *value = va_arg(args, double*);
+                               *value = this->val.p_double[i];
+                               break;
+                       }
+                       default:
+                               break;
+               }
+       }
+       return TRUE;
+}
+
+/**
+ * Implementation of database_t.query.
+ */
+static enumerator_t* query(private_mysql_database_t *this, char *sql, ...)
+{
+       MYSQL_STMT *stmt;
+       va_list args;
+       mysql_enumerator_t *enumerator = NULL;
+       conn_t *conn;
+       
+       conn = conn_get(this);
+       if (!conn)
+       {
+               return NULL;
+       }
+
+       va_start(args, sql);
+       stmt = run(conn->mysql, sql, &args);
+       if (stmt)
+       {
+               int columns, i;
+               
+               enumerator = malloc_thing(mysql_enumerator_t);
+               enumerator->public.enumerate = (void*)mysql_enumerator_enumerate;
+               enumerator->public.destroy = (void*)mysql_enumerator_destroy;
+               enumerator->stmt = stmt;
+               enumerator->conn = conn;
+               columns = mysql_stmt_field_count(stmt);
+               enumerator->bind = calloc(columns, sizeof(MYSQL_BIND));
+               enumerator->length = calloc(columns, sizeof(unsigned long));
+               enumerator->val.p_void = calloc(columns, sizeof(enumerator->val));
+               for (i = 0; i < columns; i++)
+               {
+                       switch (va_arg(args, db_type_t))
+                       {
+                               case DB_INT:
+                               {
+                                       enumerator->bind[i].buffer_type = MYSQL_TYPE_LONG;
+                                       enumerator->bind[i].buffer = (char*)&enumerator->val.p_int[i];
+                                       break;
+                               }
+                               case DB_UINT:
+                               {
+                                       enumerator->bind[i].buffer_type = MYSQL_TYPE_LONG;
+                                       enumerator->bind[i].buffer = (char*)&enumerator->val.p_uint[i];
+                                       enumerator->bind[i].is_unsigned = TRUE;
+                                       break;
+                               }
+                               case DB_TEXT:
+                               {
+                                       enumerator->bind[i].buffer_type = MYSQL_TYPE_STRING;
+                                       enumerator->bind[i].length = &enumerator->length[i];
+                                       break;
+                               }
+                               case DB_BLOB:
+                               {       
+                                       enumerator->bind[i].buffer_type = MYSQL_TYPE_BLOB;
+                                       enumerator->bind[i].length = &enumerator->length[i];
+                                       break;
+                               }
+                               case DB_DOUBLE:
+                               {
+                                       enumerator->bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
+                                       enumerator->bind[i].buffer = (char*)&enumerator->val.p_double[i];
+                                       break;
+                               }
+                               default:
+                               DBG1("invalid result data type supplied");
+                               mysql_enumerator_destroy(enumerator);
+                               va_end(args);
+                               return NULL;
+                       }
+               }
+               if (mysql_stmt_bind_result(stmt, enumerator->bind))
+               {
+                       DBG1("binding MySQL result failed: %s", mysql_stmt_error(stmt));
+               mysql_enumerator_destroy(enumerator);
+               enumerator = NULL;
+               }
+       }
+       else
+       {
+               conn_release(conn);
+       }
+       va_end(args);
+       return (enumerator_t*)enumerator;
+}
+
+/**
+ * Implementation of database_t.execute.
+ */
+static int execute(private_mysql_database_t *this, int *rowid, char *sql, ...)
+{
+       MYSQL_STMT *stmt;
+       va_list args;
+       conn_t *conn;
+       int affected = -1;
+       
+       conn = conn_get(this);
+       if (!conn)
+       {
+               return -1;
+       }
+       va_start(args, sql);
+       stmt = run(conn->mysql, sql, &args);
+       if (stmt)
+       {
+               if (rowid)
+               {
+                       *rowid = mysql_stmt_insert_id(stmt);
+               }
+               affected = mysql_stmt_affected_rows(stmt);
+               mysql_stmt_close(stmt);
+       }
+       va_end(args);
+       conn_release(conn);
+       return affected;
+}
+
+/**
+ * Implementation of database_t.destroy
+ */
+static void destroy(private_mysql_database_t *this)
+{
+       this->pool->destroy_function(this->pool, (void*)conn_destroy);
+       this->mutex->destroy(this->mutex);
+       free(this->host);
+       free(this->username);
+       free(this->password);
+       free(this->database);
+       free(this);
+}
+
+static bool parse_uri(private_mysql_database_t *this, char *uri)
+{
+       char *username, *password, *host, *port = "0", *database, *pos;
+
+       /**
+        * parse mysql://username:pass@host:port/database uri
+        */
+       username = strdupa(uri + 8);
+       pos = strchr(username, ':');
+       if (pos)
+       {
+               *pos = '\0';
+               password = pos + 1;
+               pos = strrchr(password, '@');
+               if (pos)
+               {
+                       *pos = '\0';
+                       host = pos + 1;
+                       pos = strrchr(host, ':');
+                       if (pos)
+                       {
+                               *pos = '\0';
+                               port = pos + 1;
+                               pos = strchr(port, '/');
+                       }
+                       else
+                       {
+                               pos = strchr(host, '/');
+                       }
+                       if (pos)
+                       {
+                               *pos = '\0';
+                               database = pos + 1;
+       
+                               this->host = strdup(host);
+                               this->username = strdup(username);
+                               this->password = strdup(password);
+                               this->database = strdup(database);
+                               this->port = atoi(port);
+                               return TRUE;
+                       }
+               }
+       }
+       DBG1("parsing MySQL database uri '%s' failed", uri);
+       return FALSE;
+}
+
+
+/*
+ * see header file
+ */
+mysql_database_t *mysql_database_create(char *uri)
+{
+       conn_t *conn;
+       private_mysql_database_t *this;
+       
+       if (!strneq(uri, "mysql://", 8))
+       {
+               return NULL;
+       }
+
+       this = malloc_thing(private_mysql_database_t);
+       
+       this->public.db.query = (enumerator_t* (*)(database_t *this, char *sql, ...))query;
+       this->public.db.execute = (int (*)(database_t *this, int *rowid, char *sql, ...))execute;
+       this->public.db.destroy = (void(*)(database_t*))destroy;
+       
+       if (!parse_uri(this, uri))
+       {
+               free(this);
+               return NULL;
+       }
+       this->mutex = mutex_create(MUTEX_DEFAULT);
+       this->pool = linked_list_create();
+       
+       /* check connectivity */
+       conn = conn_get(this);
+       if (!conn)
+       {
+       destroy(this);
+       return NULL;
+       }
+       conn_release(conn);
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/mysql/mysql_database.h b/src/libstrongswan/plugins/mysql/mysql_database.h
new file mode 100644 (file)
index 0000000..d04aa79
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup mysql_database mysql_database
+ * @{ @ingroup mysql_p
+ */
+
+#ifndef MYSQL_DATABASE_H_
+#define MYSQL_DATABASE_H_
+
+#include <database/database.h>
+
+typedef struct mysql_database_t mysql_database_t;
+
+/**
+ * MySQL databse_t implementation.
+ */
+struct mysql_database_t {
+
+       /**
+        * Implements database_t
+        */
+       database_t db;
+};
+
+/**
+ * Create a mysql_database instance.
+ *
+ * @param uri                  connection URI, mysql://user:pass@host:port/database
+ */
+mysql_database_t *mysql_database_create(char *uri);
+
+/**
+ * MySQL client library initialization function
+ *
+ * @return             FALSE if initialization failed
+ */
+bool mysql_database_init();
+
+/**
+ * Mysql client library cleanup function
+ */
+void mysql_database_deinit();
+
+#endif /* MYSQL_DATABASE_H_ @}*/
diff --git a/src/libstrongswan/plugins/mysql/mysql_plugin.c b/src/libstrongswan/plugins/mysql/mysql_plugin.c
new file mode 100644 (file)
index 0000000..907c746
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "mysql_plugin.h"
+
+#include <library.h>
+#include <debug.h>
+#include "mysql_database.h"
+
+typedef struct private_mysql_plugin_t private_mysql_plugin_t;
+
+/**
+ * private data of mysql_plugin
+ */
+struct private_mysql_plugin_t {
+
+       /**
+        * public functions
+        */
+       mysql_plugin_t public;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_mysql_plugin_t *this)
+{
+       lib->db->remove_database(lib->db,
+                                                        (database_constructor_t)mysql_database_create);
+       mysql_database_deinit();
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_mysql_plugin_t *this;
+       
+       if (!mysql_database_init())
+       {
+               DBG1("MySQL client library initialization failed");
+               return NULL;
+       }
+       
+       this = malloc_thing(private_mysql_plugin_t);
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->db->add_database(lib->db,
+                                                 (database_constructor_t)mysql_database_create);
+
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/mysql/mysql_plugin.h b/src/libstrongswan/plugins/mysql/mysql_plugin.h
new file mode 100644 (file)
index 0000000..dbcabaa
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup mysql_p mysql
+ * @ingroup plugins
+ *
+ * @defgroup mysql_plugin mysql_plugin
+ * @{ @ingroup mysql_p
+ */
+
+#ifndef MYSQL_PLUGIN_H_
+#define MYSQL_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct mysql_plugin_t mysql_plugin_t;
+
+/**
+ * Plugin implementing mysql database connectivity.
+ */
+struct mysql_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a mysql_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* MYSQL_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/plugin.h b/src/libstrongswan/plugins/plugin.h
new file mode 100644 (file)
index 0000000..cf0b728
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup plugin plugin
+ * @{ @ingroup plugins
+ */
+
+#ifndef PLUGIN_H_
+#define PLUGIN_H_
+
+typedef struct plugin_t plugin_t;
+
+/**
+ * Interface definition of a plugin.
+ */
+struct plugin_t {
+       
+       /**
+     * Destroy a plugin instance.
+     */
+    void (*destroy)(plugin_t *this);
+};
+
+
+/**
+ * Plugin constructor function definiton.
+ *
+ * Each plugin has a constructor functions. This function is called on daemon
+ * startup to initialize each plugin.
+ * The plugin function is named plugin_create().
+ *
+ * @return                             plugin_t instance
+ */
+typedef plugin_t *(*plugin_constructor_t)(void);
+
+#endif /* PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
new file mode 100644 (file)
index 0000000..215ed53
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * 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$
+ */
+
+#include "plugin_loader.h"
+
+#include <dlfcn.h>
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <plugins/plugin.h>
+
+typedef struct private_plugin_loader_t private_plugin_loader_t;
+
+/**
+ * private data of plugin_loader
+ */
+struct private_plugin_loader_t {
+
+       /**
+        * public functions
+        */
+       plugin_loader_t public;
+       
+       /**
+        * list of loaded plugins
+        */
+       linked_list_t *plugins;
+};
+
+/**
+ * Implementation of plugin_loader_t.load_plugins.
+ */
+static int load(private_plugin_loader_t *this, char *path, char *prefix)
+{
+       enumerator_t *enumerator;
+       char *file, *ending, *rel;
+       void *handle;
+       int count = 0;
+       
+       enumerator = enumerator_create_directory(path);
+       if (!enumerator)
+       {
+               DBG1("opening plugin directory %s failed", path);
+               return 0;
+       }
+       DBG1("loading plugins from %s", path);
+       while (enumerator->enumerate(enumerator, &rel, &file, NULL))
+       {
+               plugin_t *plugin;
+               plugin_constructor_t constructor;
+               
+               ending = file + strlen(file) - 3;
+               if (ending <= file || !streq(ending, ".so"))
+               {       /* only process .so libraries */
+                       continue;
+               }
+               if (!strneq(prefix, rel, strlen(prefix)))
+               {
+                       continue;
+               }
+               handle = dlopen(file, RTLD_LAZY);
+               if (handle == NULL)
+               {
+                       DBG1("loading plugin %s failed: %s", rel, dlerror());
+                       continue;
+               }
+               constructor = dlsym(handle, "plugin_create");
+               if (constructor == NULL)
+               {
+                       DBG1("plugin %s has no plugin_create() function, skipped", rel);
+                       dlclose(handle);
+                       continue;
+               }
+               plugin = constructor();
+               if (plugin == NULL)
+               {
+                       DBG1("plugin %s constructor failed, skipping", rel);
+                       dlclose(handle);
+                       continue;
+               }
+               DBG1("plugin %s loaded successfully", rel);
+               /* insert in front to destroy them in reverse order */
+               this->plugins->insert_last(this->plugins, plugin);
+               /* we do not store or free dlopen() handles, leak_detective requires
+                * the modules to keep loaded until leak report */
+               count++;
+       }
+       enumerator->destroy(enumerator);
+       return count;
+}
+
+/**
+ * Implementation of plugin_loader_t.destroy
+ */
+static void destroy(private_plugin_loader_t *this)
+{
+       this->plugins->destroy_offset(this->plugins, offsetof(plugin_t, destroy));
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_loader_t *plugin_loader_create()
+{
+       private_plugin_loader_t *this = malloc_thing(private_plugin_loader_t);
+       
+       this->public.load = (int(*)(plugin_loader_t*, char *path, char *prefix))load;
+       this->public.destroy = (void(*)(plugin_loader_t*))destroy;
+       
+       this->plugins = linked_list_create();
+       
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/plugin_loader.h b/src/libstrongswan/plugins/plugin_loader.h
new file mode 100644 (file)
index 0000000..4553325
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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 plugin_loader plugin_loader
+ * @{ @ingroup plugin
+ */
+
+#ifndef PLUGIN_LOADER_H_
+#define PLUGIN_LOADER_H_
+
+typedef struct plugin_loader_t plugin_loader_t;
+
+/**
+ * The plugin_loader loads plugins from a directory and initializes them
+ */
+struct plugin_loader_t {       
+       
+       /**
+        * Load plugins from a directory.
+        *
+        * @param path                  path containing loadable plugins
+        * @param prefix                prefix of plugin libraries to load
+        * @return                              number of successfully loaded plugins
+        */
+       int (*load)(plugin_loader_t *this, char *path, char *prefix);
+               
+       /**
+     * Unload loaded plugins, destroy plugin_loader instance.
+     */
+    void (*destroy)(plugin_loader_t *this);
+};
+
+/**
+ * Create a plugin_loader instance.
+ *
+ * @return                     plugin loader instance
+ */
+plugin_loader_t *plugin_loader_create();
+
+#endif /* PLUGIN_LOADER_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha1/Makefile.am b/src/libstrongswan/plugins/sha1/Makefile.am
new file mode 100644 (file)
index 0000000..299e850
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-sha1.la
+
+libstrongswan_sha1_la_SOURCES = sha1_plugin.h sha1_plugin.c sha1_hasher.c sha1_hasher.h
+libstrongswan_sha1_la_LDFLAGS = -module
+
similarity index 88%
rename from src/libstrongswan/crypto/hashers/sha1_hasher.c
rename to src/libstrongswan/plugins/sha1/sha1_hasher.c
index 6a86937ae734798130a8810e984eb2539d3a7979..97a2f207f73783df86050153cd42a6561e52c09f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file sha1_hasher.c
- * 
- * @brief Implementation of hasher_sha_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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>
+#include <arpa/inet.h>
 
 #include "sha1_hasher.h"
 
@@ -61,6 +57,11 @@ struct private_sha1_hasher_t {
         */
        sha1_hasher_t public;
        
+       /**
+        * implemented algorithm
+        */
+       hash_algorithm_t algo;
+       
        /*
         * State of the hasher.
         */
@@ -181,6 +182,32 @@ static void SHA1Final(private_sha1_hasher_t *this, u_int8_t *digest)
     }
 }
 
+/**
+ * Implementation of hasher_t.reset.
+ */
+static void reset(private_sha1_hasher_t *this)
+{
+       this->state[0] = 0x67452301;
+    this->state[1] = 0xEFCDAB89;
+    this->state[2] = 0x98BADCFE;
+    this->state[3] = 0x10325476;
+    this->state[4] = 0xC3D2E1F0;
+    this->count[0] = 0;
+    this->count[1] = 0;
+}
+
+/**
+ * copy hasher state to buf
+ */
+static void state_to_buf(private_sha1_hasher_t *this, u_int8_t *buffer)
+{
+       u_int32_t *hash = (u_int32_t*)buffer;
+       hash[0] = htonl(this->state[0]);
+       hash[1] = htonl(this->state[1]);
+       hash[2] = htonl(this->state[2]);
+       hash[3] = htonl(this->state[3]);
+       hash[4] = htonl(this->state[4]);
+}
 
 /**
  * Implementation of hasher_t.get_hash.
@@ -190,8 +217,15 @@ static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffe
        SHA1Update(this, chunk.ptr, chunk.len);
        if (buffer != NULL)
        {
-               SHA1Final(this, buffer);
-               this->public.hasher_interface.reset(&(this->public.hasher_interface));
+               if (this->algo == HASH_SHA1_NOFINAL)
+               {
+                       state_to_buf(this, buffer);
+               }
+               else
+               {
+                       SHA1Final(this, buffer);
+               }
+               reset(this);
        }
 }
 
@@ -201,18 +235,21 @@ static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffe
  */
 static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash)
 {
-       chunk_t allocated_hash;
-       
        SHA1Update(this, chunk.ptr, chunk.len);
        if (hash != NULL)
        {       
-               allocated_hash.ptr = malloc(HASH_SIZE_SHA1);
-               allocated_hash.len = HASH_SIZE_SHA1;
-               
-               SHA1Final(this, allocated_hash.ptr);
-               this->public.hasher_interface.reset(&(this->public.hasher_interface));
+               hash->ptr = malloc(HASH_SIZE_SHA1);
+               hash->len = HASH_SIZE_SHA1;
                
-               *hash = allocated_hash;
+               if (this->algo == HASH_SHA1_NOFINAL)
+               {
+                       state_to_buf(this, hash->ptr);
+               }
+               else
+               {
+                       SHA1Final(this, hash->ptr);
+               }
+               reset(this);
        }
 }
        
@@ -224,33 +261,6 @@ static size_t get_hash_size(private_sha1_hasher_t *this)
        return HASH_SIZE_SHA1;
 }
 
-/**
- * Implementation of hasher_t.reset.
- */
-static void reset(private_sha1_hasher_t *this)
-{
-       this->state[0] = 0x67452301;
-    this->state[1] = 0xEFCDAB89;
-    this->state[2] = 0x98BADCFE;
-    this->state[3] = 0x10325476;
-    this->state[4] = 0xC3D2E1F0;
-    this->count[0] = 0;
-    this->count[1] = 0;
-}
-
-/**
- * Implementation of hasher_t.get_state
- */
-static chunk_t get_state(private_sha1_hasher_t *this)
-{
-       chunk_t chunk;
-       
-       chunk.ptr = (u_char*)&this->state[0];
-       chunk.len = sizeof(this->state);
-       
-       return chunk;
-}
-
 /**
  * Implementation of hasher_t.destroy.
  */
@@ -262,15 +272,19 @@ static void destroy(private_sha1_hasher_t *this)
 /*
  * Described in header.
  */
-sha1_hasher_t *sha1_hasher_create(void)
+sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo)
 {
-       private_sha1_hasher_t *this = malloc_thing(private_sha1_hasher_t);
-       
+       private_sha1_hasher_t *this;
+       if (algo != HASH_SHA1 && algo != HASH_SHA1_NOFINAL)
+       {
+               return NULL;
+       }
+       this = malloc_thing(private_sha1_hasher_t);
+       this->algo = algo;
        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.get_state = (chunk_t (*) (hasher_t*))get_state;
        this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
        
        /* initialize */
similarity index 61%
rename from src/libstrongswan/crypto/hashers/sha1_hasher.h
rename to src/libstrongswan/plugins/sha1/sha1_hasher.h
index 380fa98459727faf2e25be1bce3bca5f397d952e..aff0eae11fb4d15e3a8c304e236bf540cfbd6da7 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file sha1_hasher.h
- * 
- * @brief Interface of sha1_hasher_t
- * 
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * for more details.
  */
 
+/**
+ * @defgroup sha1_hasher sha1_hasher
+ * @{ @ingroup sha1_p
+ */
+
 #ifndef SHA1_HASHER_H_
 #define SHA1_HASHER_H_
 
@@ -29,32 +27,24 @@ typedef struct sha1_hasher_t sha1_hasher_t;
 #include <crypto/hashers/hasher.h>
 
 /**
- * @brief Implementation of hasher_t interface using the
- * SHA1 algorithm.
- * 
- * @b Constructors:
- * - hasher_create() using HASH_SHA1 as algorithm
- * - sha1_hasher_create()
- * 
- * @see hasher_t
- * 
- * @ingroup hashers
+ * Implementation of hasher_t interface using the SHA1 algorithm.
  */
 struct sha1_hasher_t {
        
        /**
-        * Generic hasher_t interface for this hasher.
+        * Implements hasher_t interface.
         */
        hasher_t hasher_interface;
 };
 
 /**
- * @brief Creates a new sha1_hasher_t.
- * 
- * @return     sha1_hasher_t object
+ * Creates a new sha1_hasher_t.
  * 
- * @ingroup hashers
+ * This implementation supports two algorithms, HASH_SHA1 and HASH_SHA1_NOFINAL
+ *
+ * @param algo         algorithm
+ * @return                     sha1_hasher_t object
  */
-sha1_hasher_t *sha1_hasher_create(void);
+sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo);
 
-#endif /*SHA1_HASHER_H_*/
+#endif /*SHA1_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.c b/src/libstrongswan/plugins/sha1/sha1_plugin.c
new file mode 100644 (file)
index 0000000..4a69c4e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "sha1_plugin.h"
+
+#include <library.h>
+#include "sha1_hasher.h"
+
+typedef struct private_sha1_plugin_t private_sha1_plugin_t;
+
+/**
+ * private data of sha1_plugin
+ */
+struct private_sha1_plugin_t {
+
+       /**
+        * public functions
+        */
+       sha1_plugin_t public;
+};
+
+/**
+ * Implementation of sha1_plugin_t.destroy
+ */
+static void destroy(private_sha1_plugin_t *this)
+{
+       lib->crypto->remove_hasher(lib->crypto,
+                                                          (hasher_constructor_t)sha1_hasher_create);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_sha1_plugin_t *this = malloc_thing(private_sha1_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+                                                       (hasher_constructor_t)sha1_hasher_create);
+       lib->crypto->add_hasher(lib->crypto, HASH_SHA1_NOFINAL,
+                                                       (hasher_constructor_t)sha1_hasher_create);
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.h b/src/libstrongswan/plugins/sha1/sha1_plugin.h
new file mode 100644 (file)
index 0000000..82ab04c
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup sha1_p sha1
+ * @ingroup plugins
+ *
+ * @defgroup sha1_plugin sha1_plugin
+ * @{ @ingroup sha1_p
+ */
+
+#ifndef SHA1_PLUGIN_H_
+#define SHA1_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sha1_plugin_t sha1_plugin_t;
+
+/**
+ * Plugin implementing the SHA1 algorithm in software.
+ */
+struct sha1_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a sha1_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SHA1_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha2/Makefile.am b/src/libstrongswan/plugins/sha2/Makefile.am
new file mode 100644 (file)
index 0000000..066e494
--- /dev/null
@@ -0,0 +1,10 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-sha2.la
+
+libstrongswan_sha2_la_SOURCES = sha2_plugin.h sha2_plugin.c sha2_hasher.c sha2_hasher.h
+libstrongswan_sha2_la_LDFLAGS = -module
+
similarity index 94%
rename from src/libstrongswan/crypto/hashers/sha2_hasher.c
rename to src/libstrongswan/plugins/sha2/sha2_hasher.c
index b68972cec935c660ec95cf22287bb8873e66315e..1ec3970867f3a3ae7fb98567e7b04432a80e93e4 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file sha2_hasher.c
- * 
- * @brief Implementation of hasher_sha_t.
- * 
- */
-
 /*
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -21,6 +14,8 @@
  * WITHOUT ANY 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>
@@ -586,38 +581,6 @@ static void reset512(private_sha512_hasher_t *ctx)
        ctx->sha_bufCnt = 0;
 }
 
-/**
- * Implementation of hasher_t.get_state for SHA256
- */
-static chunk_t get_state256(private_sha256_hasher_t *ctx)
-{
-       chunk_t chunk;
-       chunk.ptr = (u_char*)&ctx->sha_H[0];
-       chunk.len = HASH_SIZE_SHA256;
-       return chunk;
-}
-
-/**
- * Implementation of hasher_t.get_state for SHA384
- */
-static chunk_t get_state384(private_sha512_hasher_t *ctx)
-{
-       chunk_t chunk;
-       chunk.ptr = (u_char*)&ctx->sha_H[0];
-       chunk.len = HASH_SIZE_SHA384;
-       return chunk;
-}
-/**
- * Implementation of hasher_t.get_state for SHA512
- */
-static chunk_t get_state512(private_sha512_hasher_t *ctx)
-{
-       chunk_t chunk;
-       chunk.ptr = (u_char*)&ctx->sha_H[0];
-       chunk.len = HASH_SIZE_SHA512;
-       return chunk;
-}
-
 /**
  * Implementation of hasher_t.destroy.
  */
@@ -638,7 +601,6 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
                case HASH_SHA256:
                        this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
                        this->hasher_interface.reset = (void(*)(hasher_t*))reset256;
-                       this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state256;
                        this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size256;
                        this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash256;
                        this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash256;
@@ -647,7 +609,6 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
                        /* uses SHA512 data structure */
                        this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
                        this->hasher_interface.reset = (void(*)(hasher_t*))reset384;
-                       this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state384;
                        this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size384;
                        this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash384;
                        this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash384;
@@ -655,7 +616,6 @@ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
                case HASH_SHA512:
                        this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
                        this->hasher_interface.reset = (void(*)(hasher_t*))reset512;
-                       this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state512;
                        this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size512;
                        this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash512;
                        this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash512;
similarity index 69%
rename from src/libstrongswan/crypto/hashers/sha2_hasher.h
rename to src/libstrongswan/plugins/sha2/sha2_hasher.h
index 91e82fedb7fc9c8e6d103aedbd8218ebd80386e7..6d732495a49b2afc3eae06b3eaee2c19a4aae793 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file sha2_hasher.h
- * 
- * @brief Interface of sha2_hasher_t
- * 
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * for more details.
  */
 
+/**
+ * @defgroup sha2_hasher sha2_hasher
+ * @{ @ingroup sha2_p
+ */
+
 #ifndef SHA2_HASHER_H_
 #define SHA2_HASHER_H_
 
@@ -28,18 +26,10 @@ typedef struct sha2_hasher_t sha2_hasher_t;
 #include <crypto/hashers/hasher.h>
 
 /**
- * @brief Implementation of hasher_t interface using the SHA2 algorithms.
+ * Implementation of hasher_t interface using the SHA2 algorithms.
  *
  * SHA2 is an other name for the SHA-256, SHA-384 and SHA-512 variants of
  * the SHA hash algorithm.
- *
- * @b Constructors:
- * - hasher_create() using HASH_SHA256, HASH_SHA384 or HASH_SHA512 as algorithm
- * - sha2_hasher_create()
- *
- * @see hasher_t
- * 
- * @ingroup hashers
  */
 struct sha2_hasher_t {
        
@@ -50,13 +40,11 @@ struct sha2_hasher_t {
 };
 
 /**
- * @brief Creates a new sha2_hasher_t.
+ * Creates a new sha2_hasher_t.
  * 
  * @param      algorithm       HASH_SHA256, HASH_SHA384 or HASH_SHA512
- * @return                             sha2_hasher_t object
- * 
- * @ingroup hashers
+ * @return                             sha2_hasher_t object, NULL if not supported
  */
 sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm);
 
-#endif /* SHA2_HASHER_H_ */
+#endif /* SHA2_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/sha2/sha2_plugin.c b/src/libstrongswan/plugins/sha2/sha2_plugin.c
new file mode 100644 (file)
index 0000000..993fa87
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "sha2_plugin.h"
+
+#include <library.h>
+#include "sha2_hasher.h"
+
+typedef struct private_sha2_plugin_t private_sha2_plugin_t;
+
+/**
+ * private data of sha2_plugin
+ */
+struct private_sha2_plugin_t {
+
+       /**
+        * public functions
+        */
+       sha2_plugin_t public;
+};
+
+/**
+ * Implementation of sha2_plugin_t.destroy
+ */
+static void destroy(private_sha2_plugin_t *this)
+{
+       lib->crypto->remove_hasher(lib->crypto,
+                                                          (hasher_constructor_t)sha2_hasher_create);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_sha2_plugin_t *this = malloc_thing(private_sha2_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
+                                                       (hasher_constructor_t)sha2_hasher_create);
+       lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
+                                                       (hasher_constructor_t)sha2_hasher_create);
+       lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
+                                                       (hasher_constructor_t)sha2_hasher_create);
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/sha2/sha2_plugin.h b/src/libstrongswan/plugins/sha2/sha2_plugin.h
new file mode 100644 (file)
index 0000000..8595977
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup sha2_p sha2
+ * @ingroup plugins
+ *
+ * @defgroup sha2_plugin sha2_plugin
+ * @{ @ingroup sha2_p
+ */
+
+#ifndef SHA2_PLUGIN_H_
+#define SHA2_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sha2_plugin_t sha2_plugin_t;
+
+/**
+ * Plugin implementing the SHA256, SHA384 and SHA512 algorithms in software.
+ */
+struct sha2_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a sha2_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SHA2_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.am b/src/libstrongswan/plugins/sqlite/Makefile.am
new file mode 100644 (file)
index 0000000..7c3017a
--- /dev/null
@@ -0,0 +1,12 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-sqlite.la
+
+libstrongswan_sqlite_la_SOURCES = sqlite_plugin.h sqlite_plugin.c  \
+       sqlite_database.h sqlite_database.c
+libstrongswan_sqlite_la_LDFLAGS = -module
+libstrongswan_sqlite_la_LIBADD = -lsqlite3
+
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.c b/src/libstrongswan/plugins/sqlite/sqlite_database.c
new file mode 100644 (file)
index 0000000..06a89c6
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * 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$
+ */
+
+#include "sqlite_database.h"
+
+#include <sqlite3.h>
+#include <library.h>
+#include <debug.h>
+#include <utils/mutex.h>
+
+typedef struct private_sqlite_database_t private_sqlite_database_t;
+
+/**
+ * private data of sqlite_database
+ */
+struct private_sqlite_database_t {
+
+       /**
+        * public functions
+        */
+       sqlite_database_t public;
+       
+       /**
+        * sqlite database connection
+        */
+       sqlite3 *db;
+       
+       /**
+        * mutex used to lock execute()
+        */
+       mutex_t *mutex;
+};
+
+/**
+ * Create and run a sqlite stmt using a sql string and args
+ */
+static sqlite3_stmt* run(private_sqlite_database_t *this, char *sql,
+                                                va_list *args)
+{
+       sqlite3_stmt *stmt;
+       int params, i, res = SQLITE_OK;
+       
+       if (sqlite3_prepare_v2(this->db, sql, -1, &stmt, NULL) == SQLITE_OK)
+       {
+               params = sqlite3_bind_parameter_count(stmt);
+               for (i = 1; i <= params; i++)
+               {
+                       switch (va_arg(*args, db_type_t))
+                       {
+                               case DB_INT:
+                               {
+                                       res = sqlite3_bind_int(stmt, i, va_arg(*args, int));
+                                       break;
+                               }
+                               case DB_UINT:
+                               {
+                                       res = sqlite3_bind_int64(stmt, i, va_arg(*args, u_int));
+                                       break;
+                               }
+                               case DB_TEXT:
+                               {
+                                       const char *text = va_arg(*args, const char*);
+                                       res = sqlite3_bind_text(stmt, i, text, -1, SQLITE_STATIC);
+                                       break;
+                               }
+                               case DB_BLOB:
+                               {
+                                       chunk_t c = va_arg(*args, chunk_t);
+                                       res = sqlite3_bind_blob(stmt, i, c.ptr, c.len, SQLITE_STATIC);
+                                       break;
+                               }
+                               case DB_DOUBLE:
+                               {
+                                       res = sqlite3_bind_double(stmt, i, va_arg(*args, double));
+                                       break;
+                               }
+                               case DB_NULL:
+                               {
+                                       res = sqlite3_bind_null(stmt, i);
+                                       break;
+                               }
+                               default:
+                               {
+                                       res = SQLITE_MISUSE;
+                                       break;
+                               }
+                       }
+                       if (res != SQLITE_OK)
+                       {
+                               break;
+                       }
+               }
+       }
+       if (res != SQLITE_OK)
+       {
+               sqlite3_finalize(stmt);
+               return NULL;
+       }
+       return stmt;
+}
+
+typedef struct {
+       /** implements enumerator_t */
+       enumerator_t public;
+       /** associated sqlite statement */
+       sqlite3_stmt *stmt;
+       /** number of result columns */
+       int count;
+       /** column types */
+       db_type_t *columns;
+} sqlite_enumerator_t;
+
+/**
+ * destroy a sqlite enumerator
+ */
+static void sqlite_enumerator_destroy(sqlite_enumerator_t *this)
+{
+       sqlite3_finalize(this->stmt);
+       free(this->columns);
+       free(this);
+}
+
+/**
+ * Implementation of database.query().enumerate
+ */
+static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...)
+{
+       int i;
+       va_list args;
+
+       if (sqlite3_step(this->stmt) != SQLITE_ROW)
+       {
+               return FALSE;
+       }
+       va_start(args, this);
+       for (i = 0; i < this->count; i++)
+       {
+               switch (this->columns[i])
+               {
+                       case DB_INT:
+                       {
+                               int *value = va_arg(args, int*);
+                               *value = sqlite3_column_int(this->stmt, i);
+                               break;
+                       }
+                       case DB_UINT:
+                       {
+                               u_int *value = va_arg(args, u_int*);
+                               *value = (u_int)sqlite3_column_int64(this->stmt, i);
+                               break;
+                       }
+                       case DB_TEXT:
+                       {
+                               const unsigned char **value = va_arg(args, const unsigned char**);
+                               *value = sqlite3_column_text(this->stmt, i);
+                               break;
+                       }
+                       case DB_BLOB:
+                       {
+                               chunk_t *chunk = va_arg(args, chunk_t*);
+                               chunk->len = sqlite3_column_bytes(this->stmt, i);
+                               chunk->ptr = (u_char*)sqlite3_column_blob(this->stmt, i);
+                               break;
+                       }
+                       case DB_DOUBLE:
+                       {
+                               double *value = va_arg(args, double*);
+                               *value = sqlite3_column_double(this->stmt, i);
+                               break;
+                       }
+                       default:
+                               return FALSE;
+               }
+       }
+       va_end(args);
+       return TRUE;
+}
+
+/**
+ * Implementation of database_t.query.
+ */
+static enumerator_t* query(private_sqlite_database_t *this, char *sql, ...)
+{
+       sqlite3_stmt *stmt;
+       va_list args;
+       sqlite_enumerator_t *enumerator = NULL;
+       int i;
+       
+       
+       va_start(args, sql);
+       stmt = run(this, sql, &args);
+       if (stmt)
+       {
+               enumerator = malloc_thing(sqlite_enumerator_t);
+               enumerator->public.enumerate = (void*)sqlite_enumerator_enumerate;
+               enumerator->public.destroy = (void*)sqlite_enumerator_destroy;
+               enumerator->stmt = stmt;
+               enumerator->count = sqlite3_column_count(stmt);
+               enumerator->columns = malloc(sizeof(db_type_t) * enumerator->count);
+               for (i = 0; i < enumerator->count; i++)
+               {
+                       enumerator->columns[i] = va_arg(args, db_type_t);
+               }
+       }
+       va_end(args);
+       return (enumerator_t*)enumerator;
+}
+
+/**
+ * Implementation of database_t.execute.
+ */
+static int execute(private_sqlite_database_t *this, int *rowid, char *sql, ...)
+{
+       sqlite3_stmt *stmt;
+       int affected = -1;
+       va_list args;
+       
+       /* we need a lock to get our rowid/changes correctly */
+       this->mutex->lock(this->mutex);
+       va_start(args, sql);
+       stmt = run(this, sql, &args);
+       va_end(args);
+       if (stmt)
+       {
+               if (sqlite3_step(stmt) == SQLITE_DONE)
+               {
+                       if (rowid)
+                       {
+                               *rowid = sqlite3_last_insert_rowid(this->db);
+                       }
+                       affected = sqlite3_changes(this->db);
+               }
+               sqlite3_finalize(stmt);
+       }
+       this->mutex->unlock(this->mutex);
+       return affected;
+}
+
+/**
+ * Implementation of database_t.destroy
+ */
+static void destroy(private_sqlite_database_t *this)
+{
+       sqlite3_close(this->db);
+       this->mutex->destroy(this->mutex);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+sqlite_database_t *sqlite_database_create(char *uri)
+{
+       char *file;
+       private_sqlite_database_t *this;
+       
+       /**
+        * parse sqlite:///path/to/file.db uri
+        */
+       if (!strneq(uri, "sqlite://", 9))
+       {
+               return NULL;
+       }
+       file = uri + 9;
+       
+       this = malloc_thing(private_sqlite_database_t);
+       
+       this->public.db.query = (enumerator_t* (*)(database_t *this, char *sql, ...))query;
+       this->public.db.execute = (int (*)(database_t *this, int *rowid, char *sql, ...))execute;
+       this->public.db.destroy = (void(*)(database_t*))destroy;
+       
+       if (sqlite3_open(file, &this->db) != SQLITE_OK)
+       {
+               DBG1("opening SQLite database '%s' failed", file);
+               destroy(this);
+               return NULL;
+       }
+       this->mutex = mutex_create(MUTEX_DEFAULT);
+       
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.h b/src/libstrongswan/plugins/sqlite/sqlite_database.h
new file mode 100644 (file)
index 0000000..7957856
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007-2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup sqlite_database sqlite_database
+ * @{ @ingroup sqlite_p
+ */
+
+#ifndef SQLITE_DATABASE_H_
+#define SQLITE_DATABASE_H_
+
+#include <database/database.h>
+
+typedef struct sqlite_database_t sqlite_database_t;
+
+/**
+ * sqlite databse_t implementation.
+ */
+struct sqlite_database_t {
+
+       /**
+        * Implements database_t
+        */
+       database_t db;
+};
+
+/**
+ * Create a sqlite_database instance.
+ *
+ * @param uri                  connection URI, sqlite:///path/to/file.db
+ */
+sqlite_database_t *sqlite_database_create(char *uri);
+
+#endif /* SQLITE_DATABASE_H_ @}*/
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_plugin.c b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
new file mode 100644 (file)
index 0000000..e31b572
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "sqlite_plugin.h"
+
+#include <library.h>
+#include "sqlite_database.h"
+
+typedef struct private_sqlite_plugin_t private_sqlite_plugin_t;
+
+/**
+ * private data of sqlite_plugin
+ */
+struct private_sqlite_plugin_t {
+
+       /**
+        * public functions
+        */
+       sqlite_plugin_t public;
+};
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_sqlite_plugin_t *this)
+{
+       lib->db->remove_database(lib->db,
+                                                        (database_constructor_t)sqlite_database_create);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_sqlite_plugin_t *this = malloc_thing(private_sqlite_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       lib->db->add_database(lib->db,
+                                                 (database_constructor_t)sqlite_database_create);
+
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_plugin.h b/src/libstrongswan/plugins/sqlite/sqlite_plugin.h
new file mode 100644 (file)
index 0000000..07bf961
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup sqlite_p sqlite
+ * @ingroup plugins
+ *
+ * @defgroup sqlite_plugin sqlite_plugin
+ * @{ @ingroup sqlite_p
+ */
+
+#ifndef SQLITE_PLUGIN_H_
+#define SQLITE_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct sqlite_plugin_t sqlite_plugin_t;
+
+/**
+ * Plugin implementing sqlite database connectivity
+ */
+struct sqlite_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a sqlite_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* SQLITE_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/Makefile.am b/src/libstrongswan/plugins/x509/Makefile.am
new file mode 100644 (file)
index 0000000..12441b3
--- /dev/null
@@ -0,0 +1,13 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-x509.la
+
+libstrongswan_x509_la_SOURCES = x509_plugin.h x509_plugin.c \
+  x509_cert.h x509_cert.c x509_crl.h x509_crl.c \
+  x509_ocsp_request.h x509_ocsp_request.c \
+  x509_ocsp_response.h x509_ocsp_response.c
+libstrongswan_x509_la_LDFLAGS = -module
+
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
new file mode 100644 (file)
index 0000000..47a841c
--- /dev/null
@@ -0,0 +1,1273 @@
+/*
+ * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
+ * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
+ * Copyright (C) 2002 Mario Strasser
+ * Copyright (C) 2000-2006 Andreas Steffen
+ * Copyright (C) 2006-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.
+ *
+ * $Id$
+ */
+
+#define _GNU_SOURCE
+
+#include "x509_cert.h"
+
+#include <gmp.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <crypto/hashers/hasher.h>
+#include <library.h>
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/pem.h>
+#include <utils/linked_list.h>
+#include <utils/identification.h>
+
+/**
+ * Different kinds of generalNames
+ */
+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,
+} generalNames_t;
+
+
+typedef struct private_x509_cert_t private_x509_cert_t;
+
+/**
+ * Private data of a x509_cert_t object.
+ */
+struct private_x509_cert_t {
+       /**
+        * Public interface for this certificate.
+        */
+       x509_cert_t public;
+
+       /**
+        * DER encoded X.509 certificate
+        */
+       chunk_t certificate;
+
+       /**
+        * X.509 certificate body over which signature is computed
+        */
+       chunk_t tbsCertificate;
+
+       /**
+        * Version of the X.509 certificate
+        */
+       u_int version;
+       
+       /**
+        * Serial number of the X.509 certificate
+        */
+       chunk_t serialNumber;
+       
+       /**
+        * ID representing the certificate issuer
+        */
+       identification_t *issuer;
+
+       /**
+        * Start time of certificate validity
+        */
+       time_t notBefore;
+
+       /**
+        * End time of certificate validity
+        */
+       time_t notAfter;
+
+       /**
+        * ID representing the certificate subject
+        */
+       identification_t *subject;
+       
+       /**
+        * List of subjectAltNames as identification_t
+        */
+       linked_list_t *subjectAltNames;
+       
+       /**
+        * List of crlDistributionPoints as allocated char*
+        */
+       linked_list_t *crl_uris;
+
+       /**
+        * List ocspAccessLocations as identification_t
+        */
+       linked_list_t *ocsp_uris;
+
+       /**
+        * certificates embedded public key
+        */
+       public_key_t *public_key;
+       
+       /**
+        * Subject Key Identifier
+        */
+       chunk_t subjectKeyID;
+
+       /**
+        * Authority Key Identifier
+        */
+       identification_t *authKeyIdentifier;
+
+       /**
+        * Authority Key Serial Number
+        */
+       chunk_t authKeySerialNumber;
+       
+       /**
+        * x509 constraints and other flags
+        */
+       x509_flag_t flags;
+
+       /**
+        * Signature algorithm
+        */
+       int algorithm;
+
+       /**
+        * Signature
+        */
+       chunk_t signature;
+       
+       /**
+        * reference count
+        */
+       refcount_t ref;
+};
+
+/**
+ * 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,   "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 */
+};
+
+#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_REGISTERED_ID   16
+#define GN_OBJ_ROOF                            18
+
+/**
+ * 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 */
+};
+
+#define ON_OBJ_ID_TYPE         0
+#define ON_OBJ_VALUE           1
+#define ON_OBJ_ROOF                    2
+
+/**
+ * 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 */
+};
+
+#define BASIC_CONSTRAINTS_CA   1
+#define BASIC_CONSTRAINTS_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 */
+};
+
+#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 */
+};
+
+#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
+ */
+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 */
+};
+
+#define EXT_KEY_USAGE_PURPOSE_ID       1
+#define EXT_KEY_USAGE_ROOF                     3
+
+/**
+ * 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 */
+};
+
+#define GENERAL_NAMES_GN       1
+#define GENERAL_NAMES_ROOF     3
+
+
+/**
+ * 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,       "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 */
+};
+
+#define CRL_DIST_POINTS_FULLNAME        3
+#define CRL_DIST_POINTS_ROOF           13
+
+/**
+ * ASN.1 definition of an X.509v3 x509_cert
+ */
+static const asn1Object_t certObjects[] = {
+       { 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_NONE                       }, /* 11 */
+       { 3,       "algorithm",                 ASN1_EOC,                       ASN1_RAW                        }, /* 12 */
+       { 3,       "subjectPublicKey",  ASN1_BIT_STRING,        ASN1_NONE                       }, /* 13 */
+       { 4,         "RSAPublicKey",    ASN1_SEQUENCE,          ASN1_RAW                        }, /* 14 */
+       { 2,     "issuerUniqueID",              ASN1_CONTEXT_C_1,       ASN1_OPT                        }, /* 15 */
+       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /* 16 */
+       { 2,     "subjectUniqueID",             ASN1_CONTEXT_C_2,       ASN1_OPT                        }, /* 17 */
+       { 2,     "end opt",                             ASN1_EOC,                       ASN1_END                        }, /* 18 */
+       { 2,     "optional extensions", ASN1_CONTEXT_C_3,       ASN1_OPT                        }, /* 19 */
+       { 3,       "extensions",                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 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_EXTN_ID                                               22
+#define X509_OBJ_CRITICAL                                              23
+#define X509_OBJ_EXTN_VALUE                                            24
+#define X509_OBJ_ALGORITHM                                             27
+#define X509_OBJ_SIGNATURE                                             28
+#define X509_OBJ_ROOF                                                  29
+
+
+static u_char ASN1_sAN_oid_buf[] = {
+       0x06, 0x03, 0x55, 0x1D, 0x11
+};
+static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_sAN_oid_buf);
+
+/**
+ * extracts the basicConstraints extension
+ */
+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, FALSE);
+       while (objectID < BASIC_CONSTRAINTS_ROOF) {
+
+               if (!extract_object(basicConstraintsObjects, &objectID, &object,&level, &ctx))
+               {
+                       break;
+               }
+               if (objectID == BASIC_CONSTRAINTS_CA)
+               {
+                       isCA = object.len && *object.ptr;
+                       DBG2("  %s", isCA ? "TRUE" : "FALSE");
+               }
+               objectID++;
+       }
+       return isCA;
+}
+
+/*
+ * extracts an otherName
+ */
+static bool parse_otherName(chunk_t blob, int level0)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+       int oid = OID_UNKNOWN;
+
+       asn1_init(&ctx, blob, level0, FALSE, FALSE);
+       while (objectID < ON_OBJ_ROOF)
+       {
+               if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
+               {
+                       return FALSE;
+               }
+               switch (objectID)
+               {
+                       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"))
+                                       {
+                                               return FALSE;
+                                       }
+                               }
+                               break;
+                       default:
+                               break;
+               }
+               objectID++;
+       }
+       return TRUE;
+}
+
+/*
+ * extracts a generalName
+ */
+static identification_t *parse_generalName(chunk_t blob, int level0)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       int objectID = 0;
+       u_int level;
+
+       asn1_init(&ctx, blob, level0, FALSE, FALSE);
+       while (objectID < GN_OBJ_ROOF)
+       {
+               id_type_t id_type = ID_ANY;
+       
+               if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
+               {
+                       return NULL;
+               }
+               switch (objectID)
+               {
+                       case GN_OBJ_RFC822_NAME:
+                               id_type = ID_RFC822_ADDR;
+                               break;
+                       case GN_OBJ_DNS_NAME:
+                               id_type = ID_FQDN;
+                               break;
+                       case GN_OBJ_URI:
+                               id_type = ID_DER_ASN1_GN_URI;
+                               break;
+                       case GN_OBJ_DIRECTORY_NAME:
+                               id_type = ID_DER_ASN1_DN;
+                       break;
+                       case GN_OBJ_IP_ADDRESS:
+                               id_type = ID_IPV4_ADDR;
+                               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 (id_type != ID_ANY)
+               {
+                       identification_t *gn = identification_create_from_encoding(id_type, object);
+                       DBG2("  '%D'", gn);
+                       return gn;
+        }
+               objectID++;
+    }
+    return NULL;
+}
+
+
+/**
+ * extracts one or several GNs and puts them into a chained list
+ */
+void parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+
+       asn1_init(&ctx, blob, level0, implicit, FALSE);
+       while (objectID < GENERAL_NAMES_ROOF)
+       {
+               if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
+               {
+                       return;
+               }
+               if (objectID == GENERAL_NAMES_GN)
+               {
+                       identification_t *gn = parse_generalName(object, level+1);
+
+                       if (gn != NULL)
+                       {
+                               list->insert_last(list, (void *)gn);
+                       }
+               }
+               objectID++;
+       }
+       return;
+}
+
+/**
+ * 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, FALSE);
+       if (!extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx))
+       {
+               return chunk_empty;
+       }
+       return object;
+}
+
+/**
+ * extracts an authoritykeyIdentifier
+ */
+identification_t* x509_parse_authorityKeyIdentifier(chunk_t blob, int level0,
+                                                                                               chunk_t *authKeySerialNumber)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+       identification_t *authKeyIdentifier = NULL;
+
+       *authKeySerialNumber = chunk_empty;
+
+       asn1_init(&ctx, blob, level0, FALSE, FALSE);
+       while (objectID < AUTH_KEY_ID_ROOF)
+       {
+               if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx))
+               {
+                       return NULL;
+               }
+               switch (objectID) 
+               {
+                       case AUTH_KEY_ID_KEY_ID:
+                       {
+                               chunk_t authKeyID = parse_keyIdentifier(object, level+1, TRUE);
+
+                               if (authKeyID.ptr == NULL)
+                               {
+                                       return NULL;
+                               }
+                               authKeyIdentifier = identification_create_from_encoding(
+                                                                                       ID_PUBKEY_SHA1, authKeyID); 
+                               break;
+                       }
+                       case AUTH_KEY_ID_CERT_ISSUER:
+                       {
+                               /* TODO: parse_generalNames(object, level+1, TRUE); */
+                               break;
+                       }
+                       case AUTH_KEY_ID_CERT_SERIAL:
+                               *authKeySerialNumber = object;
+                               break;
+                       default:
+                               break;
+               }
+               objectID++;
+       }
+       return authKeyIdentifier;
+}
+
+/**
+ * extracts an authorityInfoAcess location
+ */
+static void parse_authorityInfoAccess(chunk_t blob, int level0,
+                                                                         private_x509_cert_t *this)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+       int accessMethod = OID_UNKNOWN;
+       
+       asn1_init(&ctx, blob, level0, FALSE, FALSE);
+       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)
+                               {
+                                       case OID_OCSP:
+                                       case OID_CA_ISSUERS:
+                                               {
+                                                       identification_t *id;
+                                                       char *uri;
+
+                                                       id = parse_generalName(object, level+1);
+                                                       if (id == NULL)
+                                                       {       /* parsing went wrong - abort */
+                                                               return;
+                                                       }
+                                                       DBG2("  '%D'", id);
+                                                       if (accessMethod == OID_OCSP &&
+                                                               asprintf(&uri, "%D", id) > 0)
+                                                       {
+                                                               this->ocsp_uris->insert_last(this->ocsp_uris, uri);
+                                                       }
+                                                       id->destroy(id);
+                                               }
+                                               break;
+                                       default:
+                                               /* unkown accessMethod, ignoring */
+                                               break;
+                               }
+                               break;
+                       }
+                       default:
+                               break;
+               }
+               objectID++;
+       }
+}
+
+/**
+ * extracts extendedKeyUsage OIDs
+ */
+static bool parse_extendedKeyUsage(chunk_t blob, int level0)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+       
+       asn1_init(&ctx, blob, level0, FALSE, FALSE);
+       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;
+}
+
+/**
+ * extracts one or several crlDistributionPoints into a list
+ */
+static void parse_crlDistributionPoints(chunk_t blob, int level0,
+                                                                               private_x509_cert_t *this)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+       linked_list_t *list;
+       identification_t *id;
+       char *uri;
+       
+       list = linked_list_create();
+       asn1_init(&ctx, blob, level0, FALSE, FALSE);
+       while (objectID < CRL_DIST_POINTS_ROOF)
+       {
+               if (!extract_object(crlDistributionPointsObjects, &objectID, &object, &level, &ctx))
+               {
+                       list->destroy_offset(list, offsetof(identification_t, destroy));
+                       return;
+               }
+               if (objectID == CRL_DIST_POINTS_FULLNAME)
+               {       /* append extracted generalNames to existing chained list */
+                       parse_generalNames(object, level+1, TRUE, list);
+       
+                       while (list->remove_last(list, (void**)&id) == SUCCESS)
+                       {
+                               if (asprintf(&uri, "%D", id) > 0)
+                               {
+                                       this->crl_uris->insert_last(this->crl_uris, uri);
+                               }
+                               id->destroy(id);
+                       }
+               }
+               objectID++;
+       }
+       list->destroy(list);
+}
+
+/**
+ * Parses an X.509v3 certificate
+ */
+static bool parse_certificate(private_x509_cert_t *this)
+{
+       asn1_ctx_t ctx;
+       bool critical;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+       int extn_oid = OID_UNKNOWN;
+       int key_alg = 0;
+       int sig_alg = 0;
+       chunk_t subjectPublicKey = chunk_empty;
+       
+       asn1_init(&ctx, this->certificate, 0, FALSE, FALSE);
+       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_TBS_CERTIFICATE:
+                               this->tbsCertificate = object;
+                               break;
+                       case X509_OBJ_VERSION:
+                               this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
+                               DBG2("  v%d", this->version);
+                               break;
+                       case X509_OBJ_SERIAL_NUMBER:
+                               this->serialNumber = object;
+                               break;
+                       case X509_OBJ_SIG_ALG:
+                               sig_alg = parse_algorithmIdentifier(object, level, NULL);
+                               break;
+                       case X509_OBJ_ISSUER:
+                               this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
+                               DBG2("  '%D'", this->issuer);
+                               break;
+                       case X509_OBJ_NOT_BEFORE:
+                               this->notBefore = parse_time(object, level);
+                               break;
+                       case X509_OBJ_NOT_AFTER:
+                               this->notAfter = parse_time(object, level);
+                               break;
+                       case X509_OBJ_SUBJECT:
+                               this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
+                               DBG2("  '%D'", this->subject);
+                               break;
+                       case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
+                               key_alg = parse_algorithmIdentifier(object, level, NULL);
+                               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--;
+                               }
+                               break;
+                       case X509_OBJ_RSA_PUBLIC_KEY:
+                               subjectPublicKey = object;
+                               switch (key_alg)
+                               {
+                                       case OID_RSA_ENCRYPTION:
+                                               this->public_key = lib->creds->create(lib->creds,
+                                                       CRED_PUBLIC_KEY, KEY_RSA,
+                                                       BUILD_BLOB_ASN1_DER, chunk_clone(subjectPublicKey),
+                                                       BUILD_END);
+                                               break;
+                                       default:
+                                               DBG1("parsing key type %d failed", key_alg);
+                                               return FALSE;
+                               }
+                               break;
+                       case X509_OBJ_EXTN_ID:
+                               extn_oid = known_oid(object);
+                               break;
+                       case X509_OBJ_CRITICAL:
+                               critical = object.len && *object.ptr;
+                               DBG2("  %s", critical ? "TRUE" : "FALSE");
+                               break;
+                       case X509_OBJ_EXTN_VALUE:
+                       {
+                               switch (extn_oid)
+                               {
+                                       case OID_SUBJECT_KEY_ID:
+                                               this->subjectKeyID = parse_keyIdentifier(object, level, FALSE);
+                                               break;
+                                       case OID_SUBJECT_ALT_NAME:
+                                               parse_generalNames(object, level, FALSE, this->subjectAltNames);
+                                               break;
+                                       case OID_BASIC_CONSTRAINTS:
+                                               if (parse_basicConstraints(object, level))
+                                               {
+                                                       this->flags |= X509_CA;
+                                               }
+                                               break;
+                                       case OID_CRL_DISTRIBUTION_POINTS:
+                                               parse_crlDistributionPoints(object, level, this);
+                                               break;
+                                       case OID_AUTHORITY_KEY_ID:
+                                               this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
+                                                                                                               level, &this->authKeySerialNumber);
+                                               break;
+                                       case OID_AUTHORITY_INFO_ACCESS:
+                                               parse_authorityInfoAccess(object, level, this);
+                                               break;
+                                       case OID_EXTENDED_KEY_USAGE:
+                                               if (parse_extendedKeyUsage(object, level))
+                                               {
+                                                       this->flags |= X509_OCSP_SIGNER;
+                                               }
+                                               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;
+                                       default:
+                                               break;
+                               }
+                               break;
+                       }
+                       case X509_OBJ_ALGORITHM:
+                               this->algorithm = parse_algorithmIdentifier(object, level, NULL);
+                               if (this->algorithm != sig_alg)
+                               {
+                                       DBG1("  signature algorithms do not agree");
+                                       return FALSE;
+                               }
+                               break;
+                       case X509_OBJ_SIGNATURE:
+                               this->signature = object;
+                               break;
+                       default:
+                               break;
+               }
+               objectID++;
+       }
+       return TRUE;
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_cert_t *this)
+{
+       return CERT_X509;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_x509_cert_t *this)
+{
+       return this->subject;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_cert_t *this)
+{
+       return this->issuer;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_x509_cert_t *this, identification_t *subject)
+{
+       identification_t *current;
+       enumerator_t *enumerator;
+       id_match_t match, best;
+
+       best = this->subject->matches(this->subject, subject);
+       enumerator = this->subjectAltNames->create_enumerator(this->subjectAltNames);
+       while (enumerator->enumerate(enumerator, &current))
+       {
+               match = current->matches(current, subject);
+               if (match > best)
+               {
+                       best = match;   
+               }
+       }
+       enumerator->destroy(enumerator);
+       return best;    
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_x509_cert_t *this, identification_t *issuer)
+{
+       /* issuerAltNames currently not supported */
+       return this->issuer->matches(this->issuer, issuer);
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_cert_t *this, certificate_t *issuer,
+                                         bool sigcheck)
+{
+       public_key_t *key;
+       signature_scheme_t scheme;
+       bool valid;
+       x509_t *x509 = (x509_t*)issuer;
+       
+       if (&this->public.interface.interface == issuer &&
+               (this->flags & X509_SELF_SIGNED))
+       {
+               return TRUE;
+       }
+       if (issuer->get_type(issuer) != CERT_X509)
+       {
+               return FALSE;
+       }
+       if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
+       {
+               return FALSE;
+       }
+       if (!(x509->get_flags(x509) & X509_CA))
+       {
+               return FALSE;
+       }
+       if (!sigcheck)
+       {
+               return TRUE;
+       }
+       /* 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;
+               default:
+                       return FALSE;
+       }
+       key = issuer->get_public_key(issuer);
+       if (key == NULL)
+       {
+               return FALSE;
+       }
+       /* TODO: add a lightweight check option (comparing auth/subject keyids only) */
+       valid = key->verify(key, scheme, this->tbsCertificate, this->signature);
+       key->destroy(key);
+       return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_cert_t *this)
+{
+       this->public_key->get_ref(this->public_key);
+       return this->public_key;
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static private_x509_cert_t* get_ref(private_x509_cert_t *this)
+{
+       ref_get(&this->ref);
+       return this;
+}
+
+/**
+ * Implementation of x509_cert_t.set_flags.
+ */
+static void set_flags(private_x509_cert_t *this, x509_flag_t flags)
+{
+       this->flags = flags;
+}
+
+/**
+ * Implementation of x509_cert_t.get_flags.
+ */
+static x509_flag_t get_flags(private_x509_cert_t *this)
+{
+       return this->flags;
+}
+
+/**
+ * Implementation of x509_cert_t.get_validity.
+ */
+static bool get_validity(private_x509_cert_t *this, time_t *when,
+                                                time_t *not_before, time_t *not_after)
+{
+       time_t t;
+       
+       if (when)
+       {
+               t = *when;
+       }
+       else
+       {
+               t = time(NULL);
+       }
+       if (not_after)
+       {
+               *not_after = this->notAfter;
+       }
+       if (not_before)
+       {
+               *not_before = this->notBefore;
+       }
+       return (t >= this->notBefore && t <= this->notAfter);
+}
+       
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_cert_t *this)
+{
+       return chunk_clone(this->certificate);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_cert_t *this, certificate_t *other)
+{
+       if (this == (private_x509_cert_t*)other)
+       {
+               return TRUE;
+       }
+       if (other->get_type(other) != CERT_X509)
+       {
+               return FALSE;
+       }
+       /* check if we have the same X509 implementation */
+       if (other->equals == (void*)equals)
+       {
+               if (this->signature.len == 0)
+               {
+                       return FALSE;
+               }
+               return chunk_equals(this->signature, ((private_x509_cert_t*)other)->signature); 
+       }
+       /* TODO: compare against other implementation */
+       return FALSE;
+}
+
+/**
+ * Implementation of x509_t.get_serial.
+ */
+static chunk_t get_serial(private_x509_cert_t *this)
+{
+       return this->serialNumber;
+}
+
+/**
+ * Implementation of x509_t.get_authKeyIdentifier.
+ */
+static identification_t *get_authKeyIdentifier(private_x509_cert_t *this)
+{
+       return this->authKeyIdentifier;
+}
+
+/**
+ * Implementation of x509_cert_t.create_subjectAltName_enumerator.
+ */
+static enumerator_t* create_subjectAltName_enumerator(private_x509_cert_t *this)
+{
+       return this->subjectAltNames->create_enumerator(this->subjectAltNames);
+}
+
+/**
+ * Implementation of x509_cert_t.create_ocsp_uri_enumerator.
+ */
+static enumerator_t* create_ocsp_uri_enumerator(private_x509_cert_t *this)
+{
+       return this->ocsp_uris->create_enumerator(this->ocsp_uris);
+}
+
+/**
+ * Implementation of x509_cert_t.create_crl_uri_enumerator.
+ */
+static enumerator_t* create_crl_uri_enumerator(private_x509_cert_t *this)
+{
+       return this->crl_uris->create_enumerator(this->crl_uris);
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static void destroy(private_x509_cert_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               this->subjectAltNames->destroy_offset(this->subjectAltNames,
+                                                                       offsetof(identification_t, destroy));
+               this->crl_uris->destroy_function(this->crl_uris, free);
+               this->ocsp_uris->destroy_function(this->ocsp_uris, free);
+               DESTROY_IF(this->issuer);
+               DESTROY_IF(this->subject);
+               DESTROY_IF(this->public_key);
+               DESTROY_IF(this->authKeyIdentifier);
+               chunk_free(&this->certificate);
+               free(this);
+       }
+}
+
+/**
+ * load x509 certificate from a chunk
+ */
+static x509_cert_t *load(chunk_t chunk)
+{
+       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,bool))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.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.set_flags = (void (*)(x509_t*, x509_flag_t flags))set_flags;
+       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;
+       this->public.interface.create_subjectAltName_enumerator = (enumerator_t* (*)(x509_t*))create_subjectAltName_enumerator;
+       this->public.interface.create_crl_uri_enumerator = (enumerator_t* (*)(x509_t*))create_crl_uri_enumerator;
+       this->public.interface.create_ocsp_uri_enumerator = (enumerator_t* (*)(x509_t*))create_ocsp_uri_enumerator;
+
+       this->certificate = chunk;
+       this->public_key = NULL;
+       this->subject = NULL;
+       this->issuer = NULL;
+       this->subjectAltNames = linked_list_create();
+       this->crl_uris = linked_list_create();
+       this->ocsp_uris = linked_list_create();
+       this->subjectKeyID = chunk_empty;
+       this->authKeyIdentifier = NULL;
+       this->authKeySerialNumber = chunk_empty;
+       this->flags = 0;
+       this->ref = 1;
+       
+       if (!parse_certificate(this))
+       {
+               destroy(this);
+               return NULL;
+       }
+       if (issued_by(this, &this->public.interface.interface, FALSE))
+       {
+               this->flags |= X509_SELF_SIGNED;
+       }
+       return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+       /** implements the builder interface */
+       builder_t public;
+       /** loaded certificate */
+       x509_cert_t *cert;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static x509_cert_t *build(private_builder_t *this)
+{
+       x509_cert_t *cert = this->cert;
+       
+       free(this);
+       return cert;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+       va_list args;
+       
+       if (this->cert)
+       {
+               DBG1("ignoring surplus build part %N", builder_part_names, part);
+               return;
+       }
+       
+       switch (part)
+       {
+               case BUILD_BLOB_ASN1_DER:
+               {
+                       va_start(args, part);
+                       this->cert = load(va_arg(args, chunk_t));
+                       va_end(args);
+                       break;
+               }
+               default:
+                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
+                       break;
+       }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_cert_builder(certificate_type_t type)
+{
+       private_builder_t *this;
+       
+       if (type != CERT_X509)
+       {
+               return NULL;
+       }
+       
+       this = malloc_thing(private_builder_t);
+       
+       this->cert = 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/x509/x509_cert.h b/src/libstrongswan/plugins/x509/x509_cert.h
new file mode 100644 (file)
index 0000000..be6e41b
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup x509_cert x509_cert
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_CERT_H_
+#define X509_CERT_H_
+
+typedef struct x509_cert_t x509_cert_t;
+
+#include <credentials/certificates/x509.h>
+
+/**
+ * Implementation of x509_t/certificate_t using own ASN1 parser.
+ */
+struct x509_cert_t {
+
+       /**
+        * Implements the x509_t interface
+        */
+       x509_t interface;
+};
+
+/**
+ * Create the building facility for x509 certificates
+ *
+ * @param type         certificate type, CERT_X509 only
+ * @return                     builder instance to build certificate
+ */
+builder_t *x509_cert_builder(certificate_type_t type);
+
+#endif /* X509_CERT_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
new file mode 100644 (file)
index 0000000..7e2bdf2
--- /dev/null
@@ -0,0 +1,717 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "x509_crl.h"
+
+typedef struct private_x509_crl_t private_x509_crl_t;
+typedef struct revoked_t revoked_t;
+
+#include <debug.h>
+#include <library.h>
+#include <asn1/asn1.h>
+#include <credentials/certificates/x509.h>
+
+/**
+ * entry for a revoked certificate
+ */
+struct revoked_t {
+       /**
+        * serial of the revoked certificate
+        */
+       chunk_t serial;
+       
+       /**
+        * date of revocation
+        */
+       time_t date;
+       
+       /**
+        * reason for revocation
+        */
+       crl_reason_t reason;
+};
+
+/**
+ * private data of x509_crl
+ */
+struct private_x509_crl_t {
+
+       /**
+        * public functions
+        */
+       x509_crl_t public;
+       
+       /**
+        * X.509 crl in DER format
+        */
+       chunk_t certificateList;
+
+       /**
+        * X.509 crl body over which signature is computed
+        */
+       chunk_t tbsCertList;
+
+       /**
+        * Version of the X.509 crl
+        */
+       u_int version;
+       
+       /**
+        * ID representing the crl issuer
+        */
+       identification_t *issuer;
+       
+       /**
+        * CRL number
+        */
+       chunk_t crlNumber;
+
+       /**
+        * Time when the crl was generated
+        */
+       time_t thisUpdate;
+
+       /**
+        * Time when an update crl will be available
+        */
+       time_t nextUpdate;
+
+       /**
+        * list of revoked certificates as revoked_t
+        */
+       linked_list_t *revoked;
+       
+       /**
+        * Authority Key Identifier
+        */
+       identification_t *authKeyIdentifier;
+
+       /**
+        * Authority Key Serial Number
+        */
+       chunk_t authKeySerialNumber;
+       
+       /**
+        * Signature algorithm
+        */
+       int algorithm;
+       
+       /**
+        * Signature
+        */
+       chunk_t signature;
+       
+       /**
+        * reference counter
+        */
+       refcount_t ref;
+};
+
+/**
+ * from x509_cert
+ */
+extern identification_t* x509_parse_authorityKeyIdentifier(
+                                                               chunk_t blob, int level0, 
+                                                               chunk_t *authKeySerialNumber);
+
+/**
+  * 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_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_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
+
+/**
+ *  Parses an X.509 Certificate Revocation List (CRL)
+ */
+static bool parse(private_x509_crl_t *this)
+{
+       asn1_ctx_t ctx;
+       bool critical;
+       chunk_t extnID;
+       chunk_t userCertificate = chunk_empty;
+       revoked_t *revoked = NULL;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+
+       asn1_init(&ctx, this->certificateList, 0, FALSE, FALSE);
+       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_TBS_CERT_LIST:
+                               this->tbsCertList = object;
+                               break;
+                       case CRL_OBJ_VERSION:
+                               this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
+                               DBG2("  v%d", this->version);
+                               break;
+                       case CRL_OBJ_SIG_ALG:
+                               this->algorithm = parse_algorithmIdentifier(object, level, NULL);
+                               break;
+                       case CRL_OBJ_ISSUER:
+                               this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
+                               DBG2("  '%D'", this->issuer);
+                               break;
+                       case CRL_OBJ_THIS_UPDATE:
+                               this->thisUpdate = parse_time(object, level);
+                               break;
+                       case CRL_OBJ_NEXT_UPDATE:
+                               this->nextUpdate = parse_time(object, level);
+                               break;
+                       case CRL_OBJ_USER_CERTIFICATE:
+                               userCertificate = object;
+                               break;
+                       case CRL_OBJ_REVOCATION_DATE:
+                               revoked = malloc_thing(revoked_t);
+                               revoked->serial = userCertificate;
+                               revoked->date = parse_time(object, level);
+                               revoked->reason = CRL_UNSPECIFIED;
+                               this->revoked->insert_last(this->revoked, (void *)revoked);
+                               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;
+                               DBG2("  %s", critical ? "TRUE" : "FALSE");
+                               break;
+                       case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
+                       case CRL_OBJ_EXTN_VALUE:
+                               {
+                                       int extn_oid = known_oid(extnID);
+
+                                       if (revoked && extn_oid == OID_CRL_REASON_CODE)
+                                       {
+                                               if (*object.ptr == ASN1_ENUMERATED &&
+                                                       asn1_length(&object) == 1)
+                                               {
+                                                       revoked->reason = *object.ptr;
+                                               }
+                                               DBG2("  '%N'", crl_reason_names, revoked->reason);
+                                       }
+                                       else if (extn_oid == OID_AUTHORITY_KEY_ID)
+                                       {
+
+                                               this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
+                                                                                                               level, &this->authKeySerialNumber);
+                                       }
+                                       else if (extn_oid == OID_CRL_NUMBER)
+                                       {
+                                               if (!parse_asn1_simple_object(&object, ASN1_INTEGER,
+                                                                                                         level, "crlNumber"))
+                                               {
+                                                       return FALSE;
+                                               }
+                                               this->crlNumber = object;
+                                       }
+                               }
+                               break;
+                       case CRL_OBJ_ALGORITHM:
+                       {
+                               int algo = parse_algorithmIdentifier(object, level, NULL);
+                               if (this->algorithm != algo)
+                               {
+                                       DBG1("  signature algorithms do not agree");
+                                       return FALSE;
+                               }
+                               break;
+                       }
+                       case CRL_OBJ_SIGNATURE:
+                               this->signature = object;
+                               break;
+                       default:
+                               break;
+               }
+               objectID++;
+       }
+       return TRUE;
+}
+
+/**
+ * enumerator filter callback for create_enumerator
+ */
+static bool filter(void *data, revoked_t *revoked, chunk_t *serial, void *p2,
+                                  time_t *date, void *p3, crl_reason_t *reason)
+{
+       if (serial)
+       {
+               *serial = revoked->serial;
+       }
+       if (date)
+       {
+               *date = revoked->date;
+       }
+       if (reason)
+       {
+               *reason = revoked->reason;
+       }
+       return TRUE;
+}
+
+/**
+ * Implementation of crl_t.is_newer.
+ */
+static bool is_newer(private_x509_crl_t *this, crl_t *that)
+{
+       chunk_t that_crlNumber = that->get_serial(that);
+       bool new;
+       
+       /* compare crlNumbers if available - otherwise use thisUpdate */
+       if (this->crlNumber.ptr != NULL && that_crlNumber.ptr != NULL)
+       {
+               new = chunk_compare(this->crlNumber, that_crlNumber) > 0;
+               DBG1("  crl #%#B is %s - existing crl #%#B %s",
+                               &this->crlNumber, new ? "newer":"not newer",
+                               &that_crlNumber,  new ? "replaced":"retained");
+       }
+       else 
+       {
+               certificate_t *this_cert = &this->public.crl.certificate;
+               certificate_t *that_cert = &that->certificate;
+
+               time_t this_update, that_update, now = time(NULL);
+
+               this_cert->get_validity(this_cert, &now, &this_update, NULL);
+               that_cert->get_validity(that_cert, &now, &that_update, NULL);
+               new = this_update > that_update;
+               DBG1("  crl from %#T is %s - existing crl from %#T %s",
+                               &this_update, FALSE, new ? "newer":"not newer",
+                               &that_update, FALSE, new ? "replaced":"retained");
+       }
+       return new;
+}
+
+/**
+ * Implementation of crl_t.get_serial.
+ */
+static chunk_t get_serial(private_x509_crl_t *this)
+{
+       return this->crlNumber;
+}
+
+/**
+ * Implementation of crl_t.get_authKeyIdentifier.
+ */
+static identification_t* get_authKeyIdentifier(private_x509_crl_t *this)
+{
+       return this->authKeyIdentifier;
+}
+/**
+ * Implementation of crl_t.create_enumerator.
+ */
+static enumerator_t* create_enumerator(private_x509_crl_t *this)
+{
+       return enumerator_create_filter(
+                                                               this->revoked->create_enumerator(this->revoked), 
+                                                               (void*)filter, NULL, NULL);
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_crl_t *this)
+{
+       return CERT_X509_CRL;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_x509_crl_t *this)
+{
+       return this->issuer;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_crl_t *this)
+{
+       return this->issuer;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_x509_crl_t *this, identification_t *subject)
+{
+       return ID_MATCH_NONE;   
+}
+
+/**
+ * Implementation of certificate_t.has_issuer.
+ */
+static id_match_t has_issuer(private_x509_crl_t *this, identification_t *issuer)
+{
+       id_match_t match;
+
+       if (issuer->get_type(issuer) == ID_PUBKEY_SHA1)
+       {
+               if (this->authKeyIdentifier)
+               {
+                       match = issuer->matches(issuer, this->authKeyIdentifier);
+               }
+               else
+               {
+                       match = ID_MATCH_NONE;
+               }
+       }
+       else
+       {
+               match = this->issuer->matches(this->issuer, issuer);
+       }
+       return match;
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_crl_t *this, certificate_t *issuer,
+                                         bool sigcheck)
+{
+       public_key_t *key;
+       signature_scheme_t scheme;
+       bool valid;
+       x509_t *x509 = (x509_t*)issuer;
+       
+       /* check if issuer is an X.509 CA certificate */
+       if (issuer->get_type(issuer) != CERT_X509)
+       {
+               return FALSE;
+       }
+       if (!(x509->get_flags(x509) & X509_CA))
+       {
+               return FALSE;
+       }
+
+       /* get the public key of the issuer */
+       key = issuer->get_public_key(issuer);
+
+       /* compare keyIdentifiers if available, otherwise use DNs */
+       if (this->authKeyIdentifier && key)
+       {
+               identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
+
+               if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
+                                                                                 this->authKeyIdentifier))
+               {
+                       return FALSE;
+               }
+       }
+       else 
+       {
+               if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
+               {
+                       return FALSE;
+               }
+       }
+
+       if (!sigcheck)
+       {
+               return TRUE;
+       }
+       /* 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;
+               default:
+                       return FALSE;
+       }
+       if (key == NULL)
+       {
+               return FALSE;
+       }
+       valid = key->verify(key, scheme, this->tbsCertList, this->signature);
+       key->destroy(key);
+       return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_crl_t *this)
+{
+       return NULL;
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static private_x509_crl_t* get_ref(private_x509_crl_t *this)
+{
+       ref_get(&this->ref);
+       return this;
+}
+
+/**
+ * Implementation of certificate_t.get_validity.
+ */
+static bool get_validity(private_x509_crl_t *this, time_t *when,
+                                                time_t *not_before, time_t *not_after)
+{
+       time_t t;
+       
+       if (when)
+       {
+               t = *when;
+       }
+       else
+       {
+               t = time(NULL);
+       }
+       if (not_after)
+       {
+               *not_after = this->nextUpdate;
+       }
+       if (not_before)
+       {
+               *not_before = this->thisUpdate;
+       }
+       return (t <= this->nextUpdate);
+}
+       
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_crl_t *this)
+{
+       return chunk_clone(this->certificateList);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_crl_t *this, certificate_t *other)
+{
+       if ((certificate_t*)this == other)
+       {
+               return TRUE;
+       }
+       if (other->equals == (void*)equals)
+       {       /* same implementation */
+               return chunk_equals(this->signature,
+                                                       ((private_x509_crl_t*)other)->signature);
+       }
+       /* TODO: compare against other implementations */
+       return FALSE;
+}
+
+/**
+ * Implementation of certificate_t.destroy
+ */
+static void destroy(private_x509_crl_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               this->revoked->destroy_function(this->revoked, free);
+               DESTROY_IF(this->issuer);
+               DESTROY_IF(this->authKeyIdentifier);
+               free(this->certificateList.ptr);
+               free(this);
+       }
+}
+
+/**
+ * load a X509 CRL from a chunk of date (ASN1 DER)
+ */
+static x509_crl_t *load(chunk_t chunk)
+{
+       private_x509_crl_t *this = malloc_thing(private_x509_crl_t);
+       
+       this->public.crl.is_newer = (bool (*)(crl_t*,crl_t*))is_newer;
+       this->public.crl.get_serial = (chunk_t (*)(crl_t*))get_serial;
+       this->public.crl.get_authKeyIdentifier = (identification_t* (*)(crl_t*))get_authKeyIdentifier;
+       this->public.crl.create_enumerator = (enumerator_t* (*)(crl_t*))create_enumerator;
+       this->public.crl.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+       this->public.crl.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
+       this->public.crl.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+       this->public.crl.certificate.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
+       this->public.crl.certificate.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
+       this->public.crl.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
+       this->public.crl.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+       this->public.crl.certificate.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+       this->public.crl.certificate.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
+       this->public.crl.certificate.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
+       this->public.crl.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+       this->public.crl.certificate.destroy = (void (*)(certificate_t *this))destroy;
+       
+       this->certificateList = chunk;
+       this->tbsCertList = chunk_empty;
+       this->issuer = NULL;
+       this->crlNumber = chunk_empty;
+       this->revoked = linked_list_create();
+       this->authKeyIdentifier = NULL;
+       this->authKeySerialNumber = chunk_empty;
+       this->ref = 1;
+       
+       if (!parse(this))
+       {
+               destroy(this);
+               return NULL;
+       }
+       
+       return &this->public;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+       /** implements the builder interface */
+       builder_t public;
+       /** loaded CRL */
+       x509_crl_t *crl;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static x509_crl_t *build(private_builder_t *this)
+{
+       x509_crl_t *crl = this->crl;
+       
+       free(this);
+       return crl;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+       va_list args;
+       
+       if (this->crl)
+       {
+               DBG1("ignoring surplus build part %N", builder_part_names, part);
+               return;
+       }
+       
+       switch (part)
+       {
+               case BUILD_BLOB_ASN1_DER:
+               {
+                       va_start(args, part);
+                       this->crl = load(va_arg(args, chunk_t));
+                       va_end(args);
+                       break;
+               }
+               default:
+                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
+                       break;
+       }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_crl_builder(certificate_type_t type)
+{
+       private_builder_t *this;
+       
+       if (type != CERT_X509_CRL)
+       {
+               return NULL;
+       }
+       
+       this = malloc_thing(private_builder_t);
+       
+       this->crl = 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/x509/x509_crl.h b/src/libstrongswan/plugins/x509/x509_crl.h
new file mode 100644 (file)
index 0000000..0d9e5cc
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup x509_crl x509_crl
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_CRL_H_
+#define X509_CRL_H_
+
+typedef struct x509_crl_t x509_crl_t;
+
+#include <credentials/certificates/crl.h>
+
+/**
+ * Implementation of the X509 certification revocation list.
+ */
+struct x509_crl_t {
+
+       /**
+        * Implements the crl_t interface
+        */
+       crl_t crl;
+};
+
+
+/**
+ * Create the building facility for x509 certificate revocation lists.
+ *
+ * @param type         certificate type, CERT_X509_CRL only
+ * @return                     builder instance to build certificate
+ */
+builder_t *x509_crl_builder(certificate_type_t type);
+
+#endif /* X509_CRL_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
new file mode 100644 (file)
index 0000000..7e32304
--- /dev/null
@@ -0,0 +1,603 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY 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_ocsp_request.h"
+
+#include <library.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <utils/identification.h>
+#include <utils/randomizer.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+#include <credentials/certificates/x509.h>
+
+#define NONCE_LEN              16
+
+typedef struct private_x509_ocsp_request_t private_x509_ocsp_request_t;
+
+/**
+ * private data of x509_ocsp_request
+ */
+struct private_x509_ocsp_request_t {
+
+       /**
+        * public functions
+        */
+       x509_ocsp_request_t public;
+       
+       /**
+        * CA the candidates belong to
+        */
+       x509_t *ca;
+       
+       /**
+        * Requestor name, subject of cert used if not set
+        */
+       identification_t *requestor;
+
+       /**
+        * Requestor certificate, included in request
+        */
+       certificate_t *cert;
+       
+       /**
+        * Requestor private key to sign request
+        */
+       private_key_t *key;
+       
+       /**
+        * list of certificates to check, x509_t
+        */
+       linked_list_t *candidates;
+       
+       /**
+        * nonce used in request
+        */
+       chunk_t nonce;
+       
+       /**
+        * encoded OCSP request
+        */
+       chunk_t encoding;
+       
+       /**
+        * reference count
+        */
+       refcount_t ref;
+};
+
+static u_char ASN1_nonce_oid_str[] = {
+       0x06, 0x09,
+                 0x2B, 0x06,
+                               0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
+};
+
+static u_char ASN1_response_oid_str[] = {
+       0x06, 0x09,
+                 0x2B, 0x06,
+                               0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
+};
+
+static u_char ASN1_response_content_str[] = {
+       0x04, 0x0D,
+                 0x30, 0x0B,
+                               0x06, 0x09,
+                               0x2B, 0x06,
+                               0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
+};
+
+static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
+static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
+static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
+
+/**
+ * build requestorName
+ */
+static chunk_t build_requestorName(private_x509_ocsp_request_t *this)
+{
+       if (this->requestor || this->cert)
+       {       /* use requestor name, fallback to his cert subject */
+               if (!this->requestor)
+               {
+                       this->requestor = this->cert->get_subject(this->cert);
+                       this->requestor = this->requestor->clone(this->requestor);
+               }
+               return asn1_wrap(ASN1_CONTEXT_C_1, "m",
+                                       asn1_simple_object(ASN1_CONTEXT_C_4,
+                                               this->requestor->get_encoding(this->requestor)));
+       
+       }
+       return chunk_empty;
+}
+
+/**
+ * build Request, not using singleRequestExtensions
+ */
+static chunk_t build_Request(private_x509_ocsp_request_t *this,
+                                                        chunk_t issuerNameHash, chunk_t issuerKeyHash,
+                                                        chunk_t serialNumber)
+{
+       return asn1_wrap(ASN1_SEQUENCE, "m",
+                               asn1_wrap(ASN1_SEQUENCE, "cmmm",
+                                       asn1_algorithmIdentifier(OID_SHA1),
+                                       asn1_simple_object(ASN1_OCTET_STRING, issuerNameHash),
+                                       asn1_simple_object(ASN1_OCTET_STRING, issuerKeyHash),
+                                       asn1_simple_object(ASN1_INTEGER, serialNumber)));
+}
+
+/**
+ * build requestList
+ */
+static chunk_t build_requestList(private_x509_ocsp_request_t *this)
+{
+       chunk_t issuerNameHash, issuerKeyHash;
+       identification_t *issuer;
+       x509_t *x509;
+       certificate_t *cert;
+       chunk_t list = chunk_empty;
+       public_key_t *public;
+       
+       cert = (certificate_t*)this->ca;
+       public = cert->get_public_key(cert);
+       if (public)
+       {
+               hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+               if (hasher)
+               {
+                       identification_t *keyid = public->get_id(public, ID_PUBKEY_SHA1);       
+                       if (keyid)
+                       {
+                               enumerator_t *enumerator;
+                       
+                               issuerKeyHash = keyid->get_encoding(keyid);
+               
+                               issuer = cert->get_subject(cert);
+                               hasher->allocate_hash(hasher, issuer->get_encoding(issuer),
+                                                                         &issuerNameHash);
+                               hasher->destroy(hasher);
+       
+                               enumerator = this->candidates->create_enumerator(this->candidates);
+                               while (enumerator->enumerate(enumerator, &x509))
+                               {
+                                       chunk_t request, serialNumber;
+                       
+                                       serialNumber = x509->get_serial(x509);
+                                       request = build_Request(this, issuerNameHash, issuerKeyHash,
+                                                                                       serialNumber);
+                                       list = chunk_cat("mm", list, request);
+                               }
+                               enumerator->destroy(enumerator);
+                               chunk_free(&issuerNameHash);
+                       }
+               }
+               else
+               {
+                       DBG1("creating OCSP request failed, SHA1 not supported");
+               }
+               public->destroy(public);
+       }
+       else
+       {
+               DBG1("creating OCSP request failed, CA certificate has no public key");
+       }
+       return asn1_wrap(ASN1_SEQUENCE, "m", list);
+}
+
+/**
+ * build nonce extension
+ */
+static chunk_t build_nonce(private_x509_ocsp_request_t *this)
+{
+       randomizer_t *randomizer;
+       
+       randomizer = randomizer_create();
+       randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LEN, &this->nonce);
+       randomizer->destroy(randomizer);
+       
+    return asn1_wrap(ASN1_SEQUENCE, "cm", ASN1_nonce_oid,
+                               asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
+}
+
+/**
+ * build acceptableResponses extension
+ */
+static chunk_t build_acceptableResponses(private_x509_ocsp_request_t *this)
+{
+       return asn1_wrap(ASN1_SEQUENCE, "cc",
+                               ASN1_response_oid,
+                               ASN1_response_content);
+}
+
+/**
+ * build requestExtensions
+ */
+static chunk_t build_requestExtensions(private_x509_ocsp_request_t *this)
+{
+    return asn1_wrap(ASN1_CONTEXT_C_2, "m",
+                               asn1_wrap(ASN1_SEQUENCE, "mm",
+                                       build_nonce(this),
+                                       build_acceptableResponses(this)));
+}
+
+/**
+ * build tbsRequest
+ */
+static chunk_t build_tbsRequest(private_x509_ocsp_request_t *this)
+{
+       return asn1_wrap(ASN1_SEQUENCE, "mmm",
+                               build_requestorName(this),
+                               build_requestList(this),
+                               build_requestExtensions(this));
+}
+
+/**
+ * Build the optionalSignature
+ */
+static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
+                                                                          chunk_t tbsRequest)
+{
+       int oid;
+       signature_scheme_t scheme;
+       chunk_t certs, signature;
+       
+       switch (this->key->get_type(this->key))
+       {
+               /* TODO: use a generic mapping function */
+               case KEY_RSA:
+                       oid = OID_SHA1_WITH_RSA;
+                       scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+                       break;
+               default:
+                       DBG1("unable to sign OCSP request, %N signature not supported",
+                                key_type_names, this->key->get_type(this->key));
+                       return chunk_empty;
+       }
+       
+       if (!this->key->sign(this->key, scheme, tbsRequest, &signature))
+       {
+               DBG1("creating OCSP signature failed, skipped");
+               return chunk_empty;
+       }
+       if (this->cert)
+       {
+               certs = asn1_wrap(ASN1_CONTEXT_C_0, "m",
+                                       asn1_wrap(ASN1_SEQUENCE, "m",
+                                               this->cert->get_encoding(this->cert)));
+       }
+       return asn1_wrap(ASN1_CONTEXT_C_0, "m",
+                               asn1_wrap(ASN1_SEQUENCE, "cmm", 
+                                       asn1_algorithmIdentifier(oid),
+                                       asn1_bitstring("m", signature),
+                                       certs));
+}
+
+/**
+ * Build the OCSPRequest data
+ *
+ */
+static chunk_t build_OCSPRequest(private_x509_ocsp_request_t *this)
+{
+       chunk_t tbsRequest, optionalSignature = chunk_empty;
+       
+       tbsRequest = build_tbsRequest(this);
+       if (this->key)
+       {
+               optionalSignature = build_optionalSignature(this, tbsRequest);
+       }
+       return asn1_wrap(ASN1_SEQUENCE, "mm", tbsRequest, optionalSignature);
+}
+
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_ocsp_request_t *this)
+{
+       return CERT_X509_OCSP_REQUEST;
+}
+
+/**
+ * Implementation of certificate_t.get_subject
+ */
+static identification_t* get_subject(private_x509_ocsp_request_t *this)
+{
+       certificate_t *ca = (certificate_t*)this->ca;
+       
+       if (this->requestor)
+       {
+               return this->requestor;
+       }
+       if (this->cert)
+       {
+               return this->cert->get_subject(this->cert);
+       }
+       return ca->get_subject(ca);
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_ocsp_request_t *this)
+{
+       certificate_t *ca = (certificate_t*)this->ca;
+       
+       return ca->get_subject(ca);
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_subject(private_x509_ocsp_request_t *this,
+                                                         identification_t *subject)
+{
+       certificate_t *current;
+       enumerator_t *enumerator;
+       id_match_t match, best = ID_MATCH_NONE;
+
+       enumerator = this->candidates->create_enumerator(this->candidates);
+       while (enumerator->enumerate(enumerator, &current))
+       {
+               match = current->has_subject(current, subject);
+               if (match > best)
+               {
+                       best = match;   
+               }
+       }
+       enumerator->destroy(enumerator);
+       return best;    
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_x509_ocsp_request_t *this,
+                                                        identification_t *issuer)
+{
+       certificate_t *ca = (certificate_t*)this->ca;
+
+       return ca->has_subject(ca, issuer);
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_ocsp_request_t *this, certificate_t *issuer,
+                                         bool sigcheck)
+{
+       DBG1("OCSP request validation not implemented!");
+       return FALSE;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_ocsp_request_t *this)
+{
+       return NULL;
+}
+
+/**
+ * Implementation of x509_cert_t.get_validity.
+ */
+static bool get_validity(private_x509_ocsp_request_t *this, time_t *when,
+                                                time_t *not_before, time_t *not_after)
+{
+       certificate_t *cert;
+
+       if (this->cert)
+       {
+               cert = this->cert;
+       }
+       else
+       {
+               cert = (certificate_t*)this->ca;
+       }
+       return cert->get_validity(cert, when, not_before, not_after);
+}
+       
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_ocsp_request_t *this)
+{
+       return chunk_clone(this->encoding);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_ocsp_request_t *this, certificate_t *other)
+{
+       if (this == (private_x509_ocsp_request_t*)other)
+       {
+               return TRUE;
+       }
+       if (other->get_type(other) != CERT_X509_OCSP_REQUEST)
+       {
+               return FALSE;
+       }
+       /* check if we have the same X509 implementation */
+       if (other->equals == (void*)equals)
+       {
+               return chunk_equals(this->encoding, 
+                                                       ((private_x509_ocsp_request_t*)other)->encoding); 
+       }
+       /* TODO: compare against other implementation */
+       return FALSE;
+}
+
+/**
+ * Implementation of certificate_t.asdf
+ */
+static private_x509_ocsp_request_t* get_ref(private_x509_ocsp_request_t *this)
+{
+       ref_get(&this->ref);
+       return this;
+}
+
+/**
+ * Implementation of x509_ocsp_request_t.destroy
+ */
+static void destroy(private_x509_ocsp_request_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               DESTROY_IF((certificate_t*)this->ca);
+               DESTROY_IF(this->requestor);
+               DESTROY_IF(this->cert);
+               DESTROY_IF(this->key);
+               this->candidates->destroy_offset(this->candidates, offsetof(certificate_t, destroy));
+               chunk_free(&this->nonce);
+               chunk_free(&this->encoding);
+               free(this);
+       }
+}
+
+/**
+ * create an empty but initialized OCSP request
+ */
+static private_x509_ocsp_request_t *create_empty()
+{
+       private_x509_ocsp_request_t *this = malloc_thing(private_x509_ocsp_request_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,bool))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.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->ca = NULL;
+       this->requestor = NULL;
+       this->cert = NULL;
+       this->key = NULL;
+       this->nonce = chunk_empty;
+       this->encoding = chunk_empty;
+       this->candidates = linked_list_create();
+       this->ref = 1;
+       
+       return this;
+}
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+       /** implements the builder interface */
+       builder_t public;
+       /** OCSP request to build */
+       private_x509_ocsp_request_t *req;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static x509_ocsp_request_t *build(private_builder_t *this)
+{
+       private_x509_ocsp_request_t *req;
+       
+       req = this->req;
+       free(this);
+       if (req->ca)
+       {
+               req->encoding = build_OCSPRequest(req);
+               return &req->public;
+       }
+       destroy(req);
+       return NULL;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+       va_list args;
+       certificate_t *cert;
+       
+       va_start(args, part);
+       switch (part)
+       {
+               case BUILD_CA_CERT:
+                       cert = va_arg(args, certificate_t*);
+                       if (cert->get_type(cert) == CERT_X509)
+                       {
+                               this->req->ca = (x509_t*)cert;
+                       }
+                       else
+                       {
+                               cert->destroy(cert);
+                       }
+                       break;
+               case BUILD_CERT:
+                       cert = va_arg(args, certificate_t*);
+                       if (cert->get_type(cert) == CERT_X509)
+                       {
+                               this->req->candidates->insert_last(this->req->candidates, cert);
+                       }
+                       else
+                       {
+                               cert->destroy(cert);
+                       }
+                       break;
+               case BUILD_SIGNING_CERT:
+                       this->req->cert = va_arg(args, certificate_t*);
+                       break;
+               case BUILD_SIGNING_KEY:
+                       this->req->key = va_arg(args, private_key_t*);
+                       break;
+               case BUILD_SUBJECT:
+                       this->req->requestor = va_arg(args, identification_t*);
+                       break;
+               default:
+                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
+                       break;
+       }
+       va_end(args);
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_ocsp_request_builder(certificate_type_t type)
+{
+       private_builder_t *this;
+       
+       if (type != CERT_X509_OCSP_REQUEST)
+       {
+               return NULL;
+       }
+       
+       this = malloc_thing(private_builder_t);
+       
+       this->req = create_empty();
+       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/x509/x509_ocsp_request.h b/src/libstrongswan/plugins/x509/x509_ocsp_request.h
new file mode 100644 (file)
index 0000000..0a4016f
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup x509_ocsp_request x509_ocsp_request
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_OCSP_REQUEST_H_
+#define X509_OCSP_REQUEST_H_
+
+#include <credentials/certificates/ocsp_request.h>
+
+typedef struct x509_ocsp_request_t x509_ocsp_request_t;
+
+/**
+ * Implementation of ocsp_request_t using own ASN1 parser.
+ */
+struct x509_ocsp_request_t {
+
+       /**
+        * Implements the ocsp_request_t interface
+        */
+       ocsp_request_t interface;
+};
+
+/**
+ * Create the building facility for OCSP requests.
+ *
+ * The resulting builder accepts:
+ *     BUILD_CA_CERT:          CA of the checked certificates, exactly one
+ *     BUILD_CERT:                     certificates to check with the request, at least one
+ *     BUILD_SUBJECT:          subject requesting check, optional
+ *     BUILD_SIGNING_CERT:     certificate to create requestor signature, optional
+ *     BUILD_SIGNING_KEY:      private key to create requestor signature, optional
+ *
+ * @param type         certificate type, CERT_X509_OCSP_REQUEST only
+ * @return                     builder instance to build OCSP requests
+ */
+builder_t *x509_ocsp_request_builder(certificate_type_t type);
+
+#endif /* X509_OCSP_REQUEST_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
new file mode 100644 (file)
index 0000000..4ea2871
--- /dev/null
@@ -0,0 +1,928 @@
+/**
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2007 Andreas Steffen
+ * Hochschule für Technik Rapperswil
+ * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY 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_ocsp_response.h"
+
+#include <time.h>
+
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <utils/identification.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+#include <library.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+
+typedef struct private_x509_ocsp_response_t private_x509_ocsp_response_t;
+
+/**
+ * Private data of a ocsp_t object.
+ */
+struct private_x509_ocsp_response_t {
+       /**
+        * Public interface for this ocsp object.
+        */
+       x509_ocsp_response_t public;
+       
+       /**
+        * complete encoded OCSP response
+        */
+       chunk_t data;
+       
+       /**
+        * data for signature verficiation
+        */
+       chunk_t tbsResponseData;
+       
+       /**
+        * signature algorithm (OID)
+        */
+       int signatureAlgorithm;
+       
+       /**
+        * signature value
+        */
+       chunk_t signature;
+       
+       /**
+        * name or keyid of the responder
+        */
+       identification_t *responderId;
+       
+       /**
+        * time of response production
+        */
+       time_t producedAt;
+       
+       /**
+        * list of included certificates
+        */
+       linked_list_t *certs;
+
+       /**
+        * Linked list of OCSP responses, single_response_t
+        */
+       linked_list_t *responses;
+
+       /**
+        * Nonce required for ocsp request and response
+        */
+       chunk_t nonce;
+       
+       /**
+        * reference counter
+        */
+       refcount_t ref;
+};
+
+/**
+ * single response contained in OCSP response
+ */
+typedef struct {
+       /** hash algorithm OID to for the two hashes */
+       int hashAlgorithm;
+       /** hash of issuer DN */
+       chunk_t issuerNameHash;
+       /** issuerKeyID */
+       chunk_t issuerKeyHash;
+       /** serial number of certificate */
+       chunk_t serialNumber;
+       /** OCSP certificate status */
+       cert_validation_t status;
+       /** time of revocation, if revoked */
+       time_t revocationTime;
+       /** revocation reason, if revoked */
+       crl_reason_t revocationReason;
+       /** creation of associated CRL */
+       time_t thisUpdate;
+       /** creation of next CRL */
+       time_t nextUpdate;
+} single_response_t;
+
+/* our OCSP response version implementation */
+#define OCSP_BASIC_RESPONSE_VERSION 1
+
+/* 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
+};
+
+static u_char ASN1_response_oid_str[] = {
+       0x06, 0x09,
+                 0x2B, 0x06,
+                               0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
+};
+
+static u_char ASN1_response_content_str[] = {
+       0x04, 0x0D,
+                 0x30, 0x0B,
+                               0x06, 0x09,
+                               0x2B, 0x06,
+                               0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
+};
+
+static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
+static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
+static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
+
+/* asn.1 definitions for parsing */
+
+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 */
+};
+
+#define OCSP_RESPONSE_STATUS   1
+#define OCSP_RESPONSE_TYPE             4
+#define OCSP_RESPONSE                  5
+#define OCSP_RESPONSE_ROOF             7
+
+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_RAW  }, /* 24 */
+       { 2,     "end loop",                                    ASN1_EOC,                               ASN1_END  }, /* 25 */
+       { 1,   "end opt",                                               ASN1_EOC,                               ASN1_END  }  /* 26 */
+};
+
+#define BASIC_RESPONSE_TBS_DATA                 1
+#define BASIC_RESPONSE_VERSION          3
+#define BASIC_RESPONSE_ID_BY_NAME       5
+#define BASIC_RESPONSE_ID_BY_KEY        8
+#define BASIC_RESPONSE_PRODUCED_AT     10
+#define BASIC_RESPONSE_RESPONSES       11
+#define BASIC_RESPONSE_EXT_ID          15
+#define BASIC_RESPONSE_CRITICAL                16
+#define BASIC_RESPONSE_EXT_VALUE       17
+#define BASIC_RESPONSE_ALGORITHM       20
+#define BASIC_RESPONSE_SIGNATURE       21
+#define BASIC_RESPONSE_CERTIFICATE     24
+#define BASIC_RESPONSE_ROOF                    27
+
+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 */
+};
+
+#define RESPONSES_SINGLE_RESPONSE      1
+#define RESPONSES_ROOF                         3
+
+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 */
+};
+
+#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
+
+/**
+ * Implementaiton of ocsp_response_t.get_status
+ */
+static cert_validation_t get_status(private_x509_ocsp_response_t *this,
+                                                                       x509_t *subject, x509_t *issuer,
+                                                                       time_t *revocation_time,
+                                                                       crl_reason_t *revocation_reason,
+                                                                       time_t *this_update, time_t *next_update)
+{
+       enumerator_t *enumerator;
+       single_response_t *response;
+       cert_validation_t status = VALIDATION_FAILED;
+       certificate_t *issuercert = &issuer->interface;
+       
+       enumerator = this->responses->create_enumerator(this->responses);
+       while (enumerator->enumerate(enumerator, &response))
+       {
+               hasher_t *hasher;
+               identification_t *id;
+               chunk_t hash;
+               
+               /* check serial first, is cheaper */
+               if (!chunk_equals(subject->get_serial(subject), response->serialNumber))
+               {
+                       continue;
+               }
+               /* check issuerKeyHash if available */
+               if (response->issuerKeyHash.ptr)
+               {
+                       public_key_t *public;
+                       
+                       public = issuercert->get_public_key(issuercert);
+                       if (!public)
+                       {
+                               continue;
+                       }
+                       switch (response->hashAlgorithm)
+                       {       /* TODO: generic mapper function */
+                               case OID_SHA1:
+                                       id = public->get_id(public, ID_PUBKEY_SHA1);
+                                       break;
+                               default:
+                                       public->destroy(public);
+                                       continue;
+                       }
+                       if (!chunk_equals(response->issuerKeyHash, id->get_encoding(id)))
+                       {
+                               public->destroy(public);
+                               continue;
+                       }
+                       public->destroy(public);
+               }
+               /* check issuerNameHash, if available */
+               else if (response->issuerNameHash.ptr)
+               {
+                       hasher = lib->crypto->create_hasher(lib->crypto, 
+                                                       hasher_algorithm_from_oid(response->hashAlgorithm));
+                       if (!hasher)
+                       {
+                               continue;
+                       }
+                       id = issuercert->get_subject(issuercert);
+                       hasher->allocate_hash(hasher, id->get_encoding(id), &hash);
+                       hasher->destroy(hasher);
+                       if (!chunk_equals(hash, response->issuerNameHash))
+                       {
+                               continue;
+                       }
+               }
+               else
+               {
+                       continue;
+               }
+               /* got a match */
+               status = response->status;
+               *revocation_time = response->revocationTime;
+               *revocation_reason = response->revocationReason;
+               *this_update = response->thisUpdate;
+               *next_update = response->nextUpdate;
+               
+               break;
+       }
+       enumerator->destroy(enumerator);
+       return status;
+}
+
+/**
+ * Implementation of ocsp_response_t.create_cert_enumerator.
+ */
+static enumerator_t* create_cert_enumerator(private_x509_ocsp_response_t *this)
+{
+       return this->certs->create_enumerator(this->certs);
+}
+
+/**
+ * parse a single OCSP response
+ */
+static bool parse_singleResponse(private_x509_ocsp_response_t *this,
+                                                                chunk_t blob, int level0)
+{
+       u_int level;
+       asn1_ctx_t ctx;
+       chunk_t object;
+       int objectID = 0;
+       single_response_t *response;
+       
+       response = malloc_thing(single_response_t);
+       response->hashAlgorithm = OID_UNKNOWN;
+       response->issuerNameHash = chunk_empty;
+       response->issuerKeyHash = chunk_empty;
+       response->serialNumber = chunk_empty;
+       response->status = VALIDATION_FAILED;
+       response->revocationTime = 0;
+       response->revocationReason = CRL_UNSPECIFIED;
+       response->thisUpdate = 0;
+       response->nextUpdate = 0;
+
+       asn1_init(&ctx, blob, level0, FALSE, FALSE);
+       while (objectID < SINGLE_RESPONSE_ROOF)
+       {
+               if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
+               {
+                       free(response);
+                       return FALSE;
+               }
+               switch (objectID)
+               {
+                       case SINGLE_RESPONSE_ALGORITHM:
+                               response->hashAlgorithm = parse_algorithmIdentifier(object, level+1, NULL);
+                               break;
+                       case SINGLE_RESPONSE_ISSUER_NAME_HASH:
+                               response->issuerNameHash = object;
+                               break;
+                       case SINGLE_RESPONSE_ISSUER_KEY_HASH:
+                               response->issuerKeyHash = object;
+                               break;
+                       case SINGLE_RESPONSE_SERIAL_NUMBER:
+                               response->serialNumber = object;
+                               break;
+                       case SINGLE_RESPONSE_CERT_STATUS_GOOD:
+                               response->status = VALIDATION_GOOD;
+                               break;
+                       case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
+                               response->status = VALIDATION_REVOKED;
+                               break;
+                       case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
+                               response->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                               break;
+                       case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
+                               if (object.len == 1)
+                               {
+                                       response->revocationReason = *object.ptr;
+                               }
+                       break;
+                       case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
+                               response->status = VALIDATION_FAILED;
+                               break;
+                       case SINGLE_RESPONSE_THIS_UPDATE:
+                               response->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                               break;
+                       case SINGLE_RESPONSE_NEXT_UPDATE:
+                               response->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                       break;
+               }
+               objectID++;
+       }
+       this->responses->insert_last(this->responses, response);
+       return TRUE;
+}
+
+/**
+ * parse all contained responses
+ */
+static bool parse_responses(private_x509_ocsp_response_t *this, 
+                                                       chunk_t blob, int level0)
+{
+       u_int level;
+       asn1_ctx_t ctx;
+       chunk_t object;
+       int objectID = 0;
+       
+       asn1_init(&ctx, blob, level0, FALSE, FALSE);
+       while (objectID < RESPONSES_ROOF)
+       {
+               if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
+               {
+                       return FALSE;
+               }
+               switch (objectID)
+               {
+                       case RESPONSES_SINGLE_RESPONSE:
+                               if (!parse_singleResponse(this, object, level+1))
+                               {
+                                       return FALSE;
+                               }
+                               break;
+                       default:
+                               break;
+               }
+               objectID++;
+       }
+       return TRUE;
+}
+
+/**
+ * parse a basicOCSPResponse
+ */
+static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this, 
+                                                                       chunk_t blob, int level0)
+{
+       u_int level, version;
+       asn1_ctx_t ctx;
+       bool critical;
+       chunk_t object, responses = chunk_empty;
+       int objectID = 0;
+       int extn_oid = OID_UNKNOWN;
+       certificate_t *cert;
+       
+       asn1_init(&ctx, blob, level0, FALSE, FALSE);
+       while (objectID < BASIC_RESPONSE_ROOF)
+       {
+               if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
+               {
+                       return FALSE;
+               }
+               switch (objectID)
+               {
+                       case BASIC_RESPONSE_TBS_DATA:
+                               this->tbsResponseData = object;
+                               break;
+                       case BASIC_RESPONSE_VERSION:
+                               version = (object.len)? (1 + (u_int)*object.ptr) : 1;
+                               if (version != OCSP_BASIC_RESPONSE_VERSION)
+                               {
+                                       DBG1("OCSP ResponseData version %d not supported", version);
+                                       return FALSE;
+                               }
+                               break;
+                       case BASIC_RESPONSE_ID_BY_NAME:
+                               this->responderId = identification_create_from_encoding(
+                                                                                                       ID_DER_ASN1_DN, object);
+                               DBG3("  %D", this->responderId);
+                               break;
+                       case BASIC_RESPONSE_ID_BY_KEY:
+                               this->responderId = identification_create_from_encoding(
+                                                                                                       ID_PUBKEY_INFO_SHA1, object);
+                               DBG3("  %D", this->responderId);
+                               break;
+                       case BASIC_RESPONSE_PRODUCED_AT:
+                               this->producedAt = asn1totime(&object, ASN1_GENERALIZEDTIME);
+                               break;
+                       case BASIC_RESPONSE_RESPONSES:
+                               responses = object;
+                               break;
+                       case BASIC_RESPONSE_EXT_ID:
+                               extn_oid = known_oid(object);
+                               break;
+                       case BASIC_RESPONSE_CRITICAL:
+                               critical = object.len && *object.ptr;
+                               DBG3("  %s", critical ? "TRUE" : "FALSE");
+                               break;
+                       case BASIC_RESPONSE_EXT_VALUE:
+                               if (extn_oid == OID_NONCE)
+                               {
+                                       this->nonce = object;
+                               }
+                               break;
+                       case BASIC_RESPONSE_ALGORITHM:
+                               this->signatureAlgorithm = parse_algorithmIdentifier(
+                                                                                                               object, level+1, NULL);
+                               break;
+                       case BASIC_RESPONSE_SIGNATURE:
+                               this->signature = object;
+                               break;
+                       case BASIC_RESPONSE_CERTIFICATE:
+                       {
+                               cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,CERT_X509,
+                                                                                 BUILD_BLOB_ASN1_DER, chunk_clone(object),
+                                                                                 BUILD_END);
+                               if (cert)
+                               {
+                                       this->certs->insert_last(this->certs, cert);
+                               }
+                               break;
+                       }
+               }
+               objectID++;
+       }
+       if (!this->responderId)
+       {
+               this->responderId = identification_create_from_encoding(ID_ANY, chunk_empty);
+       }
+       return parse_responses(this, responses, level + 1);
+}
+
+/**
+ * Parse OCSPResponse object
+ */
+static bool parse_OCSPResponse(private_x509_ocsp_response_t *this)
+{
+       asn1_ctx_t ctx;
+       chunk_t object;
+       u_int level;
+       int objectID = 0;
+       int responseType = OID_UNKNOWN;
+       ocsp_status_t status;
+
+       asn1_init(&ctx, this->data, 0, FALSE, FALSE);
+       while (objectID < OCSP_RESPONSE_ROOF)
+       {
+               if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
+               {
+               return FALSE;
+               }
+               switch (objectID)
+               {
+                       case OCSP_RESPONSE_STATUS:
+                               status = (ocsp_status_t)*object.ptr;
+                               switch (status)
+                       {
+                               case OCSP_SUCCESSFUL:
+                                               break;
+                                       default:
+                                               DBG1("OCSP response status: %N",
+                                                        ocsp_status_names, status);
+                                               return FALSE;
+                               }
+                       break;
+                       case OCSP_RESPONSE_TYPE:
+                               responseType = known_oid(object);
+                               break;
+                       case OCSP_RESPONSE:
+                               switch (responseType)
+                               {
+                                       case OID_BASIC:
+                                               return parse_basicOCSPResponse(this, object, level+1);
+                                       default:
+                                               DBG1("OCSP response type %#B not supported", &object);
+                                               return FALSE;
+                               }
+                               break;
+               }
+               objectID++;
+       }
+       return FALSE;
+}
+
+/**
+ * Implementation of certificate_t.get_type
+ */
+static certificate_type_t get_type(private_x509_ocsp_response_t *this)
+{
+       return CERT_X509_OCSP_RESPONSE;
+}
+
+/**
+ * Implementation of certificate_t.get_issuer
+ */
+static identification_t* get_issuer(private_x509_ocsp_response_t *this)
+{
+       return this->responderId;
+}
+
+/**
+ * Implementation of certificate_t.has_subject.
+ */
+static id_match_t has_issuer(private_x509_ocsp_response_t *this,
+                                                        identification_t *issuer)
+{
+       return this->responderId->matches(this->responderId, issuer);
+}
+
+/**
+ * Implementation of certificate_t.issued_by
+ */
+static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer,
+                                         bool sigcheck)
+{
+       public_key_t *key;
+       signature_scheme_t scheme;
+       bool valid;
+       x509_t *x509 = (x509_t*)issuer;
+       
+       if (issuer->get_type(issuer) != CERT_X509)
+       {
+               return FALSE;
+       }
+       if (this->responderId->get_type(this->responderId) == ID_DER_ASN1_DN)
+       {
+               if (!this->responderId->equals(this->responderId,
+                                                                          issuer->get_subject(issuer)))
+               {
+                       return FALSE;
+               }
+       }
+       else
+       {
+               bool equal;
+               public_key_t *public = issuer->get_public_key(issuer);
+
+               if (public == NULL)
+               {
+                       return FALSE;
+               }
+               equal = this->responderId->equals(this->responderId,
+                                                                                 public->get_id(public, ID_PUBKEY_SHA1));
+               public->destroy(public);
+               if (!equal)
+               {
+                               return FALSE;
+               }
+       }
+       if (!(x509->get_flags(x509) & X509_OCSP_SIGNER))
+       {
+               return FALSE;
+       }
+       if (!sigcheck)
+       {
+               return TRUE;
+       }
+       /* 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;
+               default:
+                       return FALSE;
+       }
+       key = issuer->get_public_key(issuer);
+       if (key == NULL)
+       {
+               return FALSE;
+       }
+       valid = key->verify(key, scheme, this->tbsResponseData, this->signature);
+       key->destroy(key);
+       return valid;
+}
+
+/**
+ * Implementation of certificate_t.get_public_key
+ */
+static public_key_t* get_public_key(private_x509_ocsp_response_t *this)
+{
+       return NULL;
+}
+
+/**
+ * Implementation of x509_cert_t.get_validity.
+ */
+static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
+                                                time_t *not_before, time_t *not_after)
+{
+       time_t t;
+       
+       if (when == NULL)
+       {
+               t = time(NULL);
+       }
+       else
+       {
+               t = *when;
+       }
+       if (not_before)
+       {
+               *not_before = this->producedAt;
+       }
+       if (not_after)
+       {
+               *not_after = ~0;
+       }
+       /* valid from produceAt up to infinity */
+       if (t >= this->producedAt)
+       {
+               return TRUE;
+       }
+       return FALSE;
+}
+       
+/**
+ * Implementation of certificate_t.get_encoding.
+ */
+static chunk_t get_encoding(private_x509_ocsp_response_t *this)
+{
+       return chunk_clone(this->data);
+}
+
+/**
+ * Implementation of certificate_t.equals.
+ */
+static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
+{
+       if (this == (private_x509_ocsp_response_t*)other)
+       {
+               return TRUE;
+       }
+       if (other->get_type(other) != CERT_X509_OCSP_RESPONSE)
+       {
+               return FALSE;
+       }
+       /* check if we have the same X509 implementation */
+       if (other->equals == (void*)equals)
+       {
+               return chunk_equals(this->data, 
+                                                       ((private_x509_ocsp_response_t*)other)->data); 
+       }
+       /* TODO: compare against other implementation */
+       return FALSE;
+}
+
+/**
+ * Implementation of certificate_t.get_ref
+ */
+static private_x509_ocsp_response_t* get_ref(private_x509_ocsp_response_t *this)
+{
+       ref_get(&this->ref);
+       return this;
+}
+
+/**
+ * Implements ocsp_t.destroy.
+ */
+static void destroy(private_x509_ocsp_response_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
+               this->responses->destroy_function(this->responses, free);
+               DESTROY_IF(this->responderId);
+               free(this->data.ptr);
+               free(this);
+       }
+}
+
+/**
+ * load an OCSP response
+ */
+static x509_ocsp_response_t *load(chunk_t data)
+{
+       private_x509_ocsp_response_t *this;
+       
+       this = malloc_thing(private_x509_ocsp_response_t);
+       
+       this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
+       this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
+       this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
+       this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer;
+       this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
+       this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by;
+       this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
+       this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
+       this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding;
+       this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
+       this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
+       this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
+       this->public.interface.get_status = (cert_validation_t(*)(ocsp_response_t*, x509_t *subject, x509_t *issuer, time_t *revocation_time,crl_reason_t *revocation_reason,time_t *this_update, time_t *next_update))get_status;
+       this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator;
+       
+       this->ref = 1;
+       this->data = data;
+       this->tbsResponseData = chunk_empty;
+       this->responderId = NULL;
+       this->producedAt = UNDEFINED_TIME;
+       this->responses = linked_list_create();
+       this->nonce = chunk_empty;
+       this->signatureAlgorithm = OID_UNKNOWN;
+       this->signature = chunk_empty;
+       this->certs = linked_list_create();
+
+       if (!parse_OCSPResponse(this))
+       {
+               destroy(this);
+               return NULL;
+       }
+       return &this->public;
+}
+
+
+typedef struct private_builder_t private_builder_t;
+/**
+ * Builder implementation for certificate loading
+ */
+struct private_builder_t {
+       /** implements the builder interface */
+       builder_t public;
+       /** loaded response */
+       x509_ocsp_response_t *res;
+};
+
+/**
+ * Implementation of builder_t.build
+ */
+static x509_ocsp_response_t *build(private_builder_t *this)
+{
+       x509_ocsp_response_t *res = this->res;
+       
+       free(this);
+       return res;
+}
+
+/**
+ * Implementation of builder_t.add
+ */
+static void add(private_builder_t *this, builder_part_t part, ...)
+{
+       va_list args;
+       
+       if (this->res)
+       {
+               DBG1("ignoring surplus build part %N", builder_part_names, part);
+               return;
+       }
+       
+       switch (part)
+       {
+               case BUILD_BLOB_ASN1_DER:
+               {
+                       va_start(args, part);
+                       this->res = load(va_arg(args, chunk_t));
+                       va_end(args);
+                       break;
+               }
+               default:
+                       DBG1("ignoring unsupported build part %N", builder_part_names, part);
+                       break;
+       }
+}
+
+/**
+ * Builder construction function
+ */
+builder_t *x509_ocsp_response_builder(certificate_type_t type)
+{
+       private_builder_t *this;
+       
+       if (type != CERT_X509_OCSP_RESPONSE)
+       {
+               return NULL;
+       }
+       
+       this = malloc_thing(private_builder_t);
+       
+       this->res = 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/x509/x509_ocsp_response.h b/src/libstrongswan/plugins/x509/x509_ocsp_response.h
new file mode 100644 (file)
index 0000000..8b4c832
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup x509_ocsp_response x509_ocsp_response
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_OCSP_RESPONSE_H_
+#define X509_OCSP_RESPONSE_H_
+
+#include <credentials/certificates/ocsp_response.h>
+
+typedef struct x509_ocsp_response_t x509_ocsp_response_t;
+
+/**
+ * Implementation of ocsp_response_t using own ASN1 parser.
+ */
+struct x509_ocsp_response_t {
+
+       /**
+        * Implements the ocsp_response_t interface
+        */
+       ocsp_response_t interface;
+};
+
+/**
+ * Create the building facility for OCSP responses.
+ *
+ * @param type         certificate type, CERT_X509_OCSP_RESPONSE only
+ * @return                     builder instance to build OCSP responses
+ */
+builder_t *x509_ocsp_response_builder(certificate_type_t type);
+
+#endif /* X509_OCSP_RESPONSE_H_ @}*/
diff --git a/src/libstrongswan/plugins/x509/x509_plugin.c b/src/libstrongswan/plugins/x509/x509_plugin.c
new file mode 100644 (file)
index 0000000..8ddef3b
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "x509_plugin.h"
+
+#include <library.h>
+#include "x509_cert.h"
+#include "x509_crl.h"
+#include "x509_ocsp_request.h"
+#include "x509_ocsp_response.h"
+
+typedef struct private_x509_plugin_t private_x509_plugin_t;
+
+/**
+ * private data of x509_plugin
+ */
+struct private_x509_plugin_t {
+
+       /**
+        * public functions
+        */
+       x509_plugin_t public;
+};
+
+/**
+ * Implementation of x509_plugin_t.x509troy
+ */
+static void destroy(private_x509_plugin_t *this)
+{
+       lib->creds->remove_builder(lib->creds,
+                                                          (builder_constructor_t)x509_cert_builder);
+       lib->creds->remove_builder(lib->creds,
+                                                          (builder_constructor_t)x509_crl_builder);
+       lib->creds->remove_builder(lib->creds,
+                                                          (builder_constructor_t)x509_ocsp_request_builder);
+       lib->creds->remove_builder(lib->creds,
+                                                          (builder_constructor_t)x509_ocsp_response_builder);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_x509_plugin_t *this = malloc_thing(private_x509_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+
+       lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509,
+                                                       (builder_constructor_t)x509_cert_builder);
+       lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+                                                       (builder_constructor_t)x509_crl_builder);
+       lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
+                                                       (builder_constructor_t)x509_ocsp_request_builder);
+       lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
+                                                       (builder_constructor_t)x509_ocsp_response_builder);
+
+       return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/x509/x509_plugin.h b/src/libstrongswan/plugins/x509/x509_plugin.h
new file mode 100644 (file)
index 0000000..9743a23
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup x509_p x509
+ * @ingroup plugins
+ *
+ * @defgroup x509_plugin x509_plugin
+ * @{ @ingroup x509_p
+ */
+
+#ifndef X509_PLUGIN_H_
+#define X509_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct x509_plugin_t x509_plugin_t;
+
+/**
+ * Plugin implementing x509, CRL and OCSP certificates.
+ */
+struct x509_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a x509_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* X509_PLUGIN_H_ @}*/
index baf339640d3f6b6bf6fec2bb99960e63d91d511f..26c0cac55b395a820d74dc81677a2e88f475c0e9 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file printf_hook.c
- *
- * @brief Printf hook definitions and arginfo functions.
- *
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 "printf_hook.h"
 
-/**
- * arginfo handler in printf() pointer
- */
-int arginfo_ptr(const struct printf_info *info, size_t n, int *argtypes)
-{
-       if (n > 0)
-       {
-               argtypes[0] = PA_POINTER;
-       }
-       return 1;
-}
+#include <utils.h>
 
-/**
- * arginfo handler for two prt arguments
- */
-int arginfo_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes)
-{
-       if (n > 1)
-       {
-               argtypes[0] = PA_POINTER;
-               argtypes[1] = PA_POINTER;
-       }
-       return 2;
-}
+typedef struct private_printf_hook_t private_printf_hook_t;
 
 /**
- * arginfo handler for one ptr, one int
+ * private data of printf_hook
  */
-int arginfo_ptr_int(const struct printf_info *info, size_t n, int *argtypes)
-{
-       if (n > 1)
-       {
-               argtypes[0] = PA_POINTER;
-               argtypes[1] = PA_INT;
-       }
-       return 2;
-}
+struct private_printf_hook_t {
 
-/**
- * arginfo handler for two int arguments
- */
-int arginfo_int_int(const struct printf_info *info, size_t n, int *argtypes)
-{
-       if (n > 1)
-       {
-               argtypes[0] = PA_INT;
-               argtypes[1] = PA_INT;
-       }
-       return 2;
-}
+       /**
+        * public functions
+        */
+       printf_hook_t public;
+};
 
 /**
- * special arginfo handler respecting alt flag
+ * Implementation of printf_hook_t.add_handler.
  */
-int arginfo_int_alt_int_int(const struct printf_info *info, size_t n, int *argtypes)
+static void add_handler(private_printf_hook_t *this, char spec, 
+                                               printf_hook_functions_t hook)
 {
-       if (info->alt)
-       {
-               if (n > 1)
-               {
-                       argtypes[0] = PA_INT;
-                       argtypes[1] = PA_INT;
-               }
-               return 2;
-       }
-       
-       if (n > 0)
-       {
-               argtypes[0] = PA_INT;
-       }
-       return 1;
+       register_printf_function(spec, hook.print, hook.arginfo);
 }
 
 /**
- * special arginfo handler respecting alt flag
+ * Implementation of printf_hook_t.destroy
  */
-int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argtypes)
+static void destroy(private_printf_hook_t *this)
 {
-       if (info->alt)
-       {
-               if (n > 1)
-               {
-                       argtypes[0] = PA_POINTER;
-                       argtypes[1] = PA_INT;
-               }
-               return 2;
-       }
-       
-       if (n > 0)
-       {
-               argtypes[0] = PA_POINTER;
-       }
-       return 1;
+       free(this);
 }
 
-/**
- * special arginfo handler respecting alt flag
+/*
+ * see header file
  */
-int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes)
+printf_hook_t *printf_hook_create()
 {
-       if (info->alt)
-       {
-               if (n > 1)
-               {
-                       argtypes[0] = PA_POINTER;
-                       argtypes[1] = PA_POINTER;
-               }
-               return 2;
-       }
+       private_printf_hook_t *this = malloc_thing(private_printf_hook_t);
+       
+       this->public.add_handler = (void(*)(printf_hook_t*, char, printf_hook_functions_t))add_handler;
+       this->public.destroy = (void(*)(printf_hook_t*))destroy;
+       
        
-       if (n > 0)
-       {
-               argtypes[0] = PA_POINTER;
-       }
-       return 1;
+       return &this->public;
 }
 
index 77b228da0f32f5ef1ac624b3adc705d0e0461491..d9708c0f9a70aabc6f01fc13f56b9973f91f46ce 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file printf_hook.h
- *
- * @brief Printf hook definitions and arginfo functions.
- *
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY 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 printf_hook printf_hook
+ * @{ @ingroup libstrongswan
  */
 
 #ifndef PRINTF_HOOK_H_
 #define PRINTF_HOOK_H_
 
+typedef struct printf_hook_t printf_hook_t;
+typedef struct printf_hook_functions_t printf_hook_functions_t;
+
 #include <printf.h>
 
 /**
- * Printf() hook characters.
- * We define all characters here to have them on a central place.
+ * Printf hook function set.
+ *
+ * A printf hook has two functions, one to print the string, one to read
+ * in the number of arguments. See <printf.h>.
  */
+struct printf_hook_functions_t {
 
-/** 2 arguments: u_char *buffer, int size */
-#define PRINTF_BYTES                   'b'
-/** 1 argument: chunk_t *chunk; use #-modifier to print inline */
-#define PRINTF_CHUNK                   'B'
-/** 1 argument: identification_t *id */
-#define PRINTF_IDENTIFICATION  'D'
-/** 1 argumnet: host_t *host; use #-modifier to include port number */
-#define PRINTF_HOST                            'H'
-/** 1 argument: ike_sa_t *ike_sa */
-#define PRINTF_ENUM                            'N'
-/** 1 argument: child_sa_t *child_sa */
-#define PRINTF_TRAFFIC_SELECTOR        'R'
-/** 1 argument: time_t *time; with #-modifier 2 arguments: time_t *time, bool utc */
-#define PRINTF_TIME                            'T'
-/** 1 argument: time_t *delta; with #-modifier 2 arguments: time_t *begin, time_t *end */
-#define PRINTF_TIME_DELTA              'V'
+       /**
+        * Printf hook print function
+        */
+       printf_function *print;
+       
+       /**
+        * Printf hook arginfo function
+        */
+       printf_arginfo_function *arginfo;
+};
 
 /**
- * Generic arginfo handlers for printf() hooks
+ * Printf handler management.
  */
-int arginfo_ptr(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_int_int(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes);
-int arginfo_int_alt_int_int(const struct printf_info *info, size_t n, int *argtypes);
-
-#endif /* PRINTF_HOOK_H_ */
+struct printf_hook_t {
+       
+       /**
+        * Register a printf handler.
+        *
+        * @param spec          printf hook format character
+        * @param hook          hook functions
+        */
+       void (*add_handler)(printf_hook_t *this, char spec,
+                                               printf_hook_functions_t hook);
+       
+       /**
+     * Destroy a printf_hook instance.
+     */
+    void (*destroy)(printf_hook_t *this);
+};
+
+/**
+ * Create a printf_hook instance.
+ */
+printf_hook_t *printf_hook_create();
+
+#endif /* PRINTF_HOOK_H_ @}*/
diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c
new file mode 100644 (file)
index 0000000..57325b5
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "settings.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+
+
+typedef struct private_settings_t private_settings_t;
+typedef struct section_t section_t;
+typedef struct kv_t kv_t;
+
+/**
+ * private data of settings
+ */
+struct private_settings_t {
+
+       /**
+        * public functions
+        */
+       settings_t public;
+       
+       /**
+        * top level section
+        */
+       section_t *top;
+       
+       /**
+        * allocated file text
+        */
+       char *text;
+};
+
+/**
+ * section containing subsections and key value pairs
+ */
+struct section_t {
+
+       /**
+        * name of the section
+        */
+       char *name;
+
+       /**
+        * subsections, as section_t
+        */
+       linked_list_t *sections;
+       
+       /**
+        * key value pairs, as kv_t
+        */
+       linked_list_t *kv;
+};
+
+/**
+ * Key value pair
+ */
+struct kv_t {
+
+       /**
+        * key string, relative
+        */
+       char *key;
+       
+       /**
+        * value as string
+        */
+       char *value;
+};
+
+static char *find(section_t *section, char *key)
+{
+       char *name, *pos, *value = NULL;
+       enumerator_t *enumerator;
+       kv_t *kv;
+       section_t *current, *found = NULL;
+       
+       if (section == NULL)
+       {
+               return NULL;
+       }
+       
+       name = strdupa(key);
+       
+       pos = strchr(name, '.');
+       if (pos)
+       {
+               *pos = '\0';
+               pos++;
+               enumerator = section->sections->create_enumerator(section->sections);
+               while (enumerator->enumerate(enumerator, &current))
+               {
+                       if (streq(current->name, name))
+                       {
+                               found = current;
+                               break;
+                       }
+               }
+               enumerator->destroy(enumerator);
+               if (found)
+               {
+                       return find(found, pos);
+               }
+       }
+       else
+       {
+               enumerator = section->kv->create_enumerator(section->kv);
+               while (enumerator->enumerate(enumerator, &kv))
+               {
+                       if (streq(kv->key, name))
+                       {
+                               value = kv->value;
+                               break;
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+       return value;
+}
+
+/**
+ * Implementation of settings_t.get.
+ */
+static char* get_str(private_settings_t *this, char *key, char *def)
+{
+       char *value;
+       
+       value = find(this->top, key);
+       if (value)
+       {
+               return value;
+       }
+       return def;
+}
+
+/**
+ * Implementation of settings_t.get_bool.
+ */
+static bool get_bool(private_settings_t *this, char *key, bool def)
+{
+       char *value;
+       
+       value = find(this->top, key);
+       if (value)
+       {
+               if (strcasecmp(value, "true") == 0 ||
+                       strcasecmp(value, "enables") == 0 ||
+                       strcasecmp(value, "yes") == 0 ||
+                       strcasecmp(value, "1") == 0)
+               {
+                       return TRUE;
+               }
+               else if (strcasecmp(value, "false") == 0 ||
+                                strcasecmp(value, "disabled") == 0 ||
+                                strcasecmp(value, "no") == 0 ||
+                                strcasecmp(value, "0") == 0)
+               {
+                       return FALSE;
+               }
+       }
+       return def;
+}
+
+/**
+ * Implementation of settings_t.get_int.
+ */
+static int get_int(private_settings_t *this, char *key, int def)
+{
+       char *value;
+       int intval;
+       
+       value = find(this->top, key);
+       if (value)
+       {
+               errno = 0;
+               intval = strtol(value, NULL, 10);
+               if (errno == 0)
+               {
+                       return intval;
+               }
+       }
+       return def;
+}
+
+/**
+ * destry a section
+*/
+static void section_destroy(section_t *this)
+{
+       this->kv->destroy_function(this->kv, free);
+       this->sections->destroy_function(this->sections, (void*)section_destroy);
+       
+       free(this);
+}
+
+/**
+ * parse text, truncate "skip" chars, delimited by term respecting brackets.
+ *
+ * Chars in "skip" are truncated at the beginning and the end of the resulting
+ * token. "term" contains a list of characters to read up to (first match),
+ * while "br" contains bracket counterparts found in "term" to skip.
+ */
+static char parse(char **text, char *skip, char *term, char *br, char **token)
+{
+       char *best = NULL;
+       char best_term = '\0';
+
+       /* skip leading chars */
+       while (strchr(skip, **text))
+       {
+               (*text)++;
+               if (!**text)
+               {
+                       return 0;
+               }
+       }
+       /* mark begin of subtext */
+       *token = *text;
+       while (*term)
+       {
+               char *pos = *text;
+               int level = 1;
+               
+               /* find terminator */
+               while (*pos)
+               {
+                       if (*pos == *term)
+                       {
+                               level--;
+                       }
+                       else if (br && *pos == *br)
+                       {
+                               level++;
+                       }
+                       if (level == 0)
+                       {
+                               if (best == NULL || best > pos)
+                               {
+                                       best = pos;
+                                       best_term = *term;
+                               }
+                               break;
+                       }
+                       pos++;
+               }
+               /* try next terminator */
+               term++;
+               if (br)
+               {
+                       br++;
+               }
+       }
+       if (best)
+       {
+               /* update input */
+               *text = best;
+               /* null trailing bytes */
+               do
+               {
+                       *best = '\0';
+                       best--;
+               }
+               while (best >= *token && strchr(skip, *best));
+               /* return found terminator */
+               return best_term;
+       }
+       return 0;
+}
+
+/**
+ * Parse a section
+ */
+static section_t* parse_section(char **text, char *name)
+{
+       section_t *sub, *section;
+       bool finished = FALSE;
+       char *key, *value, *inner;
+       
+       static int lev = 0;
+       lev++;
+       
+       section = malloc_thing(section_t);
+       section->name = name;
+       section->sections = linked_list_create();
+       section->kv = linked_list_create();
+       
+       while (!finished)
+       {
+               switch (parse(text, "\t\n ", "{=#", NULL, &key))
+               {
+                       case '{':
+                               if (parse(text, "\t ", "}", "{", &inner))
+                               {
+                                       sub = parse_section(&inner, key);
+                                       if (sub)
+                                       {
+                                               section->sections->insert_last(section->sections, sub);
+                                               continue;
+                                       }
+                               }
+                               break;
+                       case '=':
+                               if (parse(text, "\t ", "\n", NULL, &value))
+                               {
+                                       kv_t *kv = malloc_thing(kv_t);
+                                       kv->key = key;
+                                       kv->value = value;
+                                       section->kv->insert_last(section->kv, kv);
+                                       continue;
+                               }
+                               break;
+                       case '#':
+                               parse(text, "", "\n", NULL, &value);
+                               continue;
+                       default:
+                               finished = TRUE;
+                               continue;
+               }
+               section_destroy(section);
+               return NULL;
+       }
+       return section;
+}
+
+/**
+ * Implementation of settings_t.destroy
+ */
+static void destroy(private_settings_t *this)
+{
+       if (this->top)
+       {
+               section_destroy(this->top);
+       }
+       free(this->text);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+settings_t *settings_create(char *file)
+{
+       private_settings_t *this = malloc_thing(private_settings_t);
+       
+       this->public.get_str = (char*(*)(settings_t*, char *key, char* def))get_str;
+       this->public.get_int = (int(*)(settings_t*, char *key, bool def))get_int;
+       this->public.get_bool = (bool(*)(settings_t*, char *key, bool def))get_bool;
+       this->public.destroy = (void(*)(settings_t*))destroy;
+       
+       this->top = NULL;
+       this->text = NULL;
+       
+       if (file)
+       {
+               FILE *fd;
+               int len;
+               char *pos;
+       
+               fd = fopen(file, "r");
+               if (fd == NULL)
+               {
+                       return &this->public;
+               }
+               fseek(fd, 0, SEEK_END);
+               len = ftell(fd);
+               rewind(fd);
+               this->text = malloc(len + 1);
+               this->text[len] = '\0';
+               if (fread(this->text, 1, len, fd) != len)
+               {
+                       free(this->text);
+                       this->text = NULL;
+                       return &this->public;
+               }
+               fclose(fd);
+
+               pos = this->text;
+               this->top = parse_section(&pos, NULL);
+               if (this->top == NULL)
+               {
+                       free(this->text);
+                       this->text = NULL;
+                       return &this->public;
+               }
+       }
+       return &this->public;
+}
+
diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h
new file mode 100644 (file)
index 0000000..9177097
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup settings settings
+ * @{ @ingroup libstrongswan
+ */
+
+#ifndef SETTINGS_H_
+#define SETTINGS_H_
+
+typedef struct settings_t settings_t;
+
+#include <library.h>
+
+/**
+ * Generic configuration options read from a config file.
+ *
+ * The sytax is quite simple:
+ *
+ * settings := (section|keyvalue)*
+ * section  := name { settings }
+ * keyvalue := key = value\n
+ *
+ * E.g.:
+ * @code
+   a = b
+   section-one {
+               somevalue = asdf
+               subsection {
+                       othervalue = xxx
+               }
+               yetanother = zz
+       }
+       section-two {
+       }
+       @endcode
+ *
+ * The values are accesses using the get() functions using dotted keys, e.g.
+ *   section-one.subsection.othervalue
+ */
+struct settings_t {
+
+       /**
+        * Get a settings value as a string.
+        *
+        * @param key           key including sections
+        * @param def           value returned if key not found
+        * @return                      value pointing to internal string
+        */
+       char* (*get_str)(settings_t *this, char *key, char *def);
+       
+       /**
+        * Get a boolean yes|no, true|false value.
+        *
+        * @param jey           key including sections
+        * @param def           default value returned if key not found
+        * @return                      value of the key
+        */
+       bool (*get_bool)(settings_t *this, char *key, bool def);
+       
+       /**
+        * Get an integer value.
+        *
+        * @param key           key including sections
+        * @param def           default value to return if key not found
+        * @return                      value of the key
+        */
+       int (*get_int)(settings_t *this, char *key, bool def);
+       
+       /**
+     * Destroy a settings instance.
+     */
+    void (*destroy)(settings_t *this);
+};
+
+/**
+ * Load setings from a file.
+ */
+settings_t *settings_create(char *file);
+
+#endif /* SETTINGS_H_ @}*/
diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c
new file mode 100644 (file)
index 0000000..d6920cf
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2005-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.
+ *
+ * $Id$
+ */
+
+#include "utils.h"
+
+#include <string.h>
+#include <pthread.h>
+#include <stdio.h>
+
+#include <enum.h>
+
+ENUM(status_names, SUCCESS, DESTROY_ME,
+       "SUCCESS",
+       "FAILED",
+       "OUT_OF_RES",
+       "ALREADY_DONE",
+       "NOT_SUPPORTED",
+       "INVALID_ARG",
+       "NOT_FOUND",
+       "PARSE_ERROR",
+       "VERIFY_ERROR",
+       "INVALID_STATE",
+       "DESTROY_ME",
+       "NEED_MORE",
+);
+
+/**
+ * Described in header.
+ */
+void *clalloc(void * pointer, size_t size)
+{
+       void *data;
+       data = malloc(size);
+       
+       memcpy(data, pointer, size);
+       
+       return (data);
+}
+
+/**
+ * Described in header.
+ */
+void memxor(u_int8_t dest[], u_int8_t src[], size_t n)
+{
+       size_t i;
+       for (i = 0; i < n; i++)
+       {
+               dest[i] ^= src[i];
+       }
+}
+
+/**
+ * We use a single mutex for all refcount variables. This
+ * is not optimal for performance, but the critical section
+ * is not that long...
+ * TODO: Consider to include a mutex in each refcount_t variable.
+ */
+static pthread_mutex_t ref_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Described in header.
+ * 
+ * TODO: May be implemented with atomic CPU instructions
+ * instead of a mutex.
+ */
+void ref_get(refcount_t *ref)
+{
+       pthread_mutex_lock(&ref_mutex);
+       (*ref)++;
+       pthread_mutex_unlock(&ref_mutex);
+}
+
+/**
+ * Described in header.
+ * 
+ * TODO: May be implemented with atomic CPU instructions
+ * instead of a mutex.
+ */
+bool ref_put(refcount_t *ref)
+{
+       bool more_refs;
+       
+       pthread_mutex_lock(&ref_mutex);
+       more_refs = --(*ref);
+       pthread_mutex_unlock(&ref_mutex);
+       return !more_refs;
+}
+
+/**
+ * output handler in printf() for time_t
+ */
+static int time_print(FILE *stream, const struct printf_info *info,
+                                         const void *const *args)
+{
+       static const char* months[] = {
+               "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+       };
+       time_t *time = *((time_t**)(args[0]));
+       bool utc = TRUE;
+       struct tm t;
+       
+       if (info->alt)
+       {
+               utc = *((bool*)(args[1]));
+       }
+       if (time == UNDEFINED_TIME)
+       {
+               return fprintf(stream, "--- -- --:--:--%s----",
+                                          info->alt ? " UTC " : " ");
+       }
+       if (utc)
+       {
+               gmtime_r(time, &t);
+       }
+       else
+       {
+               localtime_r(time, &t);
+       }
+       return fprintf(stream, "%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);
+}
+
+/**
+ * arginfo handler for printf() time
+ */
+static int time_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+       if (info->alt)
+       {
+               if (n > 1)
+               {
+                       argtypes[0] = PA_POINTER;
+                       argtypes[1] = PA_INT;
+               }
+               return 2;
+       }
+       
+       if (n > 0)
+       {
+               argtypes[0] = PA_POINTER;
+       }
+       return 1;
+}
+
+/**
+ * output handler in printf() for time deltas
+ */
+static int time_delta_print(FILE *stream, const struct printf_info *info,
+                                                       const void *const *args)
+{
+       char* unit = "second";
+       time_t *arg1, *arg2;
+       time_t delta;
+       
+       arg1 = *((time_t**)(args[0]));
+       if (info->alt)
+       {
+               arg2 = *((time_t**)(args[1]));
+               delta = abs(*arg1 - *arg2);
+       }
+       else
+       {
+               delta = *arg1;
+       }
+
+       if (delta > 2 * 60 * 60 * 24)
+       {
+               delta /= 60 * 60 * 24;
+               unit = "day";
+       }
+       else if (delta > 2 * 60 * 60)
+       {
+               delta /= 60 * 60;
+               unit = "hour";
+       }
+       else if (delta > 2 * 60)
+       {
+               delta /= 60;
+               unit = "minute";
+       }
+       return fprintf(stream, "%d %s%s", delta, unit, (delta == 1)? "":"s");
+}
+
+/**
+ * arginfo handler for printf() time deltas
+ */
+int time_delta_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+       if (info->alt)
+       {
+               if (n > 1)
+               {
+                       argtypes[0] = PA_POINTER;
+                       argtypes[1] = PA_POINTER;
+               }
+               return 2;
+       }
+       
+       if (n > 0)
+       {
+               argtypes[0] = PA_POINTER;
+       }
+       return 1;
+}
+
+/**
+ * Number of bytes per line to dump raw data
+ */
+#define BYTES_PER_LINE 16
+
+static char hexdig_upper[] = "0123456789ABCDEF";
+
+/**
+ * output handler in printf() for mem ranges
+ */
+static int mem_print(FILE *stream, const struct printf_info *info,
+                                        const void *const *args)
+{
+       char *bytes = *((void**)(args[0]));
+       int len = *((size_t*)(args[1]));
+       
+       char buffer[BYTES_PER_LINE * 3];
+       char ascii_buffer[BYTES_PER_LINE + 1];
+       char *buffer_pos = buffer;
+       char *bytes_pos  = bytes;
+       char *bytes_roof = bytes + len;
+       int line_start = 0;
+       int i = 0;
+       int written = 0;
+       
+       written += fprintf(stream, "=> %d bytes @ %p", len, bytes);
+       
+       while (bytes_pos < bytes_roof)
+       {
+               *buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF];
+               *buffer_pos++ = hexdig_upper[ *bytes_pos       & 0xF];
+
+               ascii_buffer[i++] =
+                               (*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.';
+
+               if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE) 
+               {
+                       int padding = 3 * (BYTES_PER_LINE - i);
+                       int written;
+                       
+                       while (padding--)
+                       {
+                               *buffer_pos++ = ' ';
+                       }
+                       *buffer_pos++ = '\0';
+                       ascii_buffer[i] = '\0';
+                       
+                       written += fprintf(stream, "\n%4d: %s  %s",
+                                                          line_start, buffer, ascii_buffer);
+
+                       
+                       buffer_pos = buffer;
+                       line_start += BYTES_PER_LINE;
+                       i = 0;
+               }
+               else
+               {
+                       *buffer_pos++ = ' ';
+               }
+       }
+       return written;
+}
+
+/**
+ * arginfo handler for printf() mem ranges
+ */
+int mem_arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+       if (n > 1)
+       {
+               argtypes[0] = PA_POINTER;
+               argtypes[1] = PA_INT;
+       }
+       return 2;
+}
+
+/**
+ * return printf hook functions for a time
+ */
+printf_hook_functions_t time_get_printf_hooks()
+{
+       printf_hook_functions_t hooks = {time_print, time_arginfo};
+       
+       return hooks;
+}
+
+/**
+ * return printf hook functions for a time delta
+ */
+printf_hook_functions_t time_delta_get_printf_hooks()
+{
+       printf_hook_functions_t hooks = {time_delta_print, time_delta_arginfo};
+       
+       return hooks;
+}
+
+/**
+ * return printf hook functions for mem ranges
+ */
+printf_hook_functions_t mem_get_printf_hooks()
+{
+       printf_hook_functions_t hooks = {mem_print, mem_arginfo};
+       
+       return hooks;
+}
+
diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h
new file mode 100644 (file)
index 0000000..2624c31
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup utils utils
+ * @{ @ingroup libstrongswan
+ */
+
+#ifndef UTILS_H_
+#define UTILS_H_
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#include <enum.h>
+
+/**
+ * Number of bits in a byte
+ */
+#define BITS_PER_BYTE 8
+
+/**
+ * Default length for various auxiliary text buffers
+ */
+#define BUF_LEN 512
+
+/**
+ * Macro compares two strings for equality
+ */
+#define streq(x,y) (strcmp(x, y) == 0)
+
+/**
+ * Macro compares two strings for equality
+ */
+#define strneq(x,y,len) (strncmp(x, y, len) == 0)
+
+/**
+ * Macro compares two binary blobs for equality
+ */
+#define memeq(x,y,len) (memcmp(x, y, len) == 0)
+
+/**
+ * Macro gives back larger of two values.
+ */
+#define max(x,y) ((x) > (y) ? (x):(y))
+
+/**
+ * Macro gives back smaller of two values.
+ */
+#define min(x,y) ((x) < (y) ? (x):(y))
+
+/**
+ * Call destructor of an object, if object != NULL
+ */
+#define DESTROY_IF(obj) if (obj) (obj)->destroy(obj)
+
+/**
+ * Call offset destructor of an object, if object != NULL
+ */
+#define DESTROY_OFFSET_IF(obj, offset) if (obj) obj->destroy_offset(obj, offset);
+
+/**
+ * Call function destructor of an object, if object != NULL
+ */
+#define DESTROY_FUNCTION_IF(obj, fn) if (obj) obj->destroy_function(obj, fn);
+
+/**
+ * Debug macro to follow control flow
+ */
+#define POS printf("%s, line %d\n", __FILE__, __LINE__)
+
+/**
+ * Macro to allocate a sized type.
+ */
+#define malloc_thing(thing) ((thing*)malloc(sizeof(thing)))
+
+/**
+ * Assign a function as a class method
+ */
+#define ASSIGN(method, function) (method = (typeof(method))function)
+
+/**
+ * time_t not defined
+ */
+#define UNDEFINED_TIME 0
+
+/**
+ * General purpose boolean type.
+ */
+typedef int bool;
+#define FALSE 0
+#define TRUE  1
+
+typedef enum status_t status_t;
+
+/**
+ * Return values of function calls.
+ */
+enum status_t {
+       /**
+        * Call succeeded.
+        */
+       SUCCESS,
+       
+       /**
+        * Call failed.
+        */
+       FAILED,
+       
+       /**
+        * Out of resources.
+        */
+       OUT_OF_RES,
+       
+       /**
+        * The suggested operation is already done
+        */
+       ALREADY_DONE,
+       
+       /**
+        * Not supported.
+        */
+       NOT_SUPPORTED,
+       
+       /**
+        * One of the arguments is invalid.
+        */
+       INVALID_ARG,
+       
+       /**
+        * Something could not be found.
+        */
+       NOT_FOUND,
+       
+       /**
+        * Error while parsing.
+        */
+       PARSE_ERROR,
+       
+       /**
+        * Error while verifying.
+        */
+       VERIFY_ERROR,
+       
+       /**
+        * Object in invalid state.
+        */
+       INVALID_STATE,
+       
+       /**
+        * Destroy object which called method belongs to.
+        */
+       DESTROY_ME,
+       
+       /**
+        * Another call to the method is required.
+        */
+       NEED_MORE,
+};
+
+/**
+ * enum_names for type status_t.
+ */
+extern enum_name_t *status_names;
+
+/**
+ * deprecated pluto style return value:
+ * error message, NULL for success
+ */
+typedef const char *err_t;
+
+/**
+ * Handle struct timeval like an own type.
+ */
+typedef struct timeval timeval_t;
+
+/**
+ * Handle struct timespec like an own type.
+ */
+typedef struct timespec timespec_t;
+
+/**
+ * Handle struct chunk_t like an own type.
+ */
+typedef struct sockaddr sockaddr_t;
+
+/**
+ * Clone a data to a newly allocated buffer
+ */
+void *clalloc(void *pointer, size_t size);
+
+/**
+ * Same as memcpy, but XORs src into dst instead of copy
+ */
+void memxor(u_int8_t dest[], u_int8_t src[], size_t n);
+
+/**
+ * Special type to count references
+ */
+typedef volatile u_int refcount_t;
+
+/**
+ * Get a new reference.
+ *
+ * Increments the reference counter atomic.
+ *
+ * @param ref  pointer to ref counter
+ */
+void ref_get(refcount_t *ref);
+
+/**
+ * Put back a unused reference.
+ *
+ * Decrements the reference counter atomic and 
+ * says if more references available.
+ *
+ * @param ref  pointer to ref counter
+ * @return             TRUE if no more references counted
+ */
+bool ref_put(refcount_t *ref);
+
+/**
+ * Get printf hooks for time.
+ *
+ * Arguments are: 
+ *    time_t* time
+ * Arguments using #-specificer
+ *    time_t* time, bool utc
+ */
+printf_hook_functions_t time_get_printf_hooks();
+
+/**
+ * Get printf hooks for time deltas.
+ *
+ * Arguments are: 
+ *    time_t* delta
+ * Arguments using #-specificer
+ *    time_t* begin, time_t* end
+ */
+printf_hook_functions_t time_delta_get_printf_hooks();
+
+/**
+ * Get printf hooks for time deltas.
+ *
+ * Arguments are: 
+ *    u_char *ptr, int len
+ */
+printf_hook_functions_t mem_get_printf_hooks();
+
+#endif /* UTILS_H_ @}*/
index 842a2e9973dc256f82227f233a559c193fed756a..67d0c8d1abbac88b87f3b70d75feac7548bc23e8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file enumerator.c
- *
- * @brief Implementation of enumerator_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 "enumerator.h"
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include <debug.h>
 
 /**
  * Implementation of enumerator_create_empty().enumerate
@@ -42,3 +45,350 @@ enumerator_t* enumerator_create_empty()
        return this;
 }
 
+/**
+ * Enumerator implementation for directory enumerator
+ */
+typedef struct {
+       /** implements enumerator_t */
+       enumerator_t public;
+       /** directory handle */
+       DIR *dir;
+       /** absolute path of current file */
+       char full[PATH_MAX];
+       /** where directory part of full ends and relative file gets written */
+       char *full_end;
+} dir_enum_t;
+
+/**
+ * Implementation of enumerator_create_directory().destroy
+ */
+static void destroy_dir_enum(dir_enum_t *this)
+{
+       closedir(this->dir);
+       free(this);
+}
+
+/**
+ * Implementation of enumerator_create_directory().enumerate
+ */
+static bool enumerate_dir_enum(dir_enum_t *this, char **relative,
+                                                          char **absolute, struct stat *st)
+{
+       struct dirent *entry = readdir(this->dir);
+       size_t len, remaining;
+       
+       if (!entry)
+       {
+               return FALSE;
+       }
+       if (streq(entry->d_name, ".") || streq(entry->d_name, ".."))
+       {
+               return enumerate_dir_enum(this, relative, absolute, st);
+       }
+       if (relative)
+       {
+               *relative = entry->d_name;
+       }
+       if (absolute || st)
+       {       
+               remaining = sizeof(this->full) - (this->full_end - this->full);
+               len = snprintf(this->full_end, remaining, "%s", entry->d_name);
+               if (len < 0 || len >= remaining)
+               {
+                       DBG1("buffer too small to enumerate file '%s'", entry->d_name);
+                       return FALSE;
+               }
+               if (absolute)
+               {
+                       *absolute = this->full;
+               }
+               if (st)
+               {
+                       if (stat(this->full, st))
+                       {
+                               DBG1("stat() on '%s' failed: %s", this->full, strerror(errno));
+                               return FALSE;
+                       }
+               }
+       }
+       return TRUE;
+}
+
+/**
+ * See header
+ */
+enumerator_t* enumerator_create_directory(char *path)
+{
+       size_t len;
+       dir_enum_t *this = malloc_thing(dir_enum_t);
+       this->public.enumerate = (void*)enumerate_dir_enum;
+       this->public.destroy = (void*)destroy_dir_enum;
+       
+       if (*path == '\0')
+       {
+               path = "./";
+       }
+       len = snprintf(this->full, sizeof(this->full)-1, "%s", path);
+       if (len < 0 || len >= sizeof(this->full)-1)
+       {
+               DBG1("path string %s too long", path);
+               free(this);
+               return NULL;
+       }
+       /* append a '/' if not already done */
+       if (this->full[len-1] != '/')
+       {
+               this->full[len++] = '/';
+               this->full[len] = '\0';
+       }
+       this->full_end = &this->full[len];
+       
+       this->dir = opendir(path);
+       if (this->dir == NULL)
+       {
+               DBG1("opening directory %s failed: %s", path, strerror(errno));
+               free(this);
+               return NULL;
+       }
+       return &this->public;
+}
+
+/**
+ * enumerator for nested enumerations
+ */
+typedef struct {
+       /* implements enumerator_t */
+       enumerator_t public;
+       /* outer enumerator */
+       enumerator_t *outer;
+       /* inner enumerator */
+       enumerator_t *inner;
+       /* constructor for inner enumerator */
+       enumerator_t *(*create_inner)(void *outer, void *data);
+       /* data to pass to constructor above */
+       void *data;
+       /* destructor for data */
+       void (*destroy_data)(void *data);
+} nested_enumerator_t;
+
+
+/**
+ * Implementation of enumerator_create_nested().enumerate()
+ */
+static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2,
+                                                        void *v3, void *v4, void *v5)
+{
+       while (TRUE)
+       {
+               while (this->inner == NULL)
+               {       
+                       void *outer;
+                       
+                       if (!this->outer->enumerate(this->outer, &outer))
+                       {
+                               return FALSE;
+                       }
+                       this->inner = this->create_inner(outer, this->data);
+               }
+               if (this->inner->enumerate(this->inner, v1, v2, v3, v4, v5))
+               {
+                       return TRUE;
+               }
+               this->inner->destroy(this->inner);
+               this->inner = NULL;
+       }
+}
+
+/**
+ * Implementation of enumerator_create_nested().destroy()
+ **/
+static void destroy_nested(nested_enumerator_t *this)
+{
+       if (this->destroy_data)
+       {
+               this->destroy_data(this->data);
+       }
+       DESTROY_IF(this->inner);
+       this->outer->destroy(this->outer);
+       free(this);
+}
+
+/**
+ * See header
+ */
+enumerator_t *enumerator_create_nested(enumerator_t *outer,
+                                       enumerator_t *(inner_constructor)(void *outer, void *data),
+                                       void *data, void (*destroy_data)(void *data))
+{
+       nested_enumerator_t *enumerator = malloc_thing(nested_enumerator_t);
+       
+       enumerator->public.enumerate = (void*)enumerate_nested;
+       enumerator->public.destroy = (void*)destroy_nested;
+       enumerator->outer = outer;
+       enumerator->inner = NULL;
+       enumerator->create_inner = (void*)inner_constructor;
+       enumerator->data = data;
+       enumerator->destroy_data = destroy_data;
+       
+       return &enumerator->public;
+}
+
+/**
+ * enumerator for filtered enumerator
+ */
+typedef struct {
+       enumerator_t public;
+       enumerator_t *unfiltered;
+       void *data;
+       bool (*filter)(void *data, ...);
+       void (*destructor)(void *data);
+} filter_enumerator_t;
+
+/**
+ * Implementation of enumerator_create_filter().destroy
+ */
+void destroy_filter(filter_enumerator_t *this)
+{
+       if (this->destructor)
+       {
+               this->destructor(this->data);
+       }
+       this->unfiltered->destroy(this->unfiltered);
+       free(this);
+}
+
+/**
+ * Implementation of enumerator_create_filter().enumerate
+ */
+bool enumerate_filter(filter_enumerator_t *this, void *o1, void *o2,
+                                         void *o3, void *o4, void *o5)
+{
+       void *i1, *i2, *i3, *i4, *i5;
+
+       while (this->unfiltered->enumerate(this->unfiltered, &i1, &i2, &i3, &i4, &i5))
+       {
+               if (this->filter(this->data, &i1, o1, &i2, o2, &i3, o3, &i4, o4, &i5, o5))
+               {
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+/**
+ * see header
+ */
+enumerator_t *enumerator_create_filter(enumerator_t *unfiltered,
+                                                                          bool (*filter)(void *data, ...),
+                                                                          void *data, void (*destructor)(void *data))
+{
+       filter_enumerator_t *this = malloc_thing(filter_enumerator_t);
+       
+       this->public.enumerate = (void*)enumerate_filter;
+       this->public.destroy = (void*)destroy_filter;
+       this->unfiltered = unfiltered;
+       this->filter = filter;
+       this->data = data;
+       this->destructor = destructor;
+       
+       return &this->public;
+}
+
+/**
+ * enumerator for cleaner enumerator
+ */
+typedef struct {
+       enumerator_t public;
+       enumerator_t *wrapped;
+       void (*cleanup)(void *data);
+       void *data;
+} cleaner_enumerator_t;
+
+/**
+ * Implementation of enumerator_create_cleanup().destroy
+ */
+static void destroy_cleaner(cleaner_enumerator_t *this)
+{
+       this->cleanup(this->data);
+       this->wrapped->destroy(this->wrapped);
+       free(this);
+}
+
+/**
+ * Implementation of enumerator_create_cleaner().enumerate
+ */
+static bool enumerate_cleaner(cleaner_enumerator_t *this, void *v1, void *v2,
+                                                         void *v3, void *v4, void *v5)
+{
+       return this->wrapped->enumerate(this->wrapped, v1, v2, v3, v4, v5);
+}
+
+/**
+ * see header
+ */
+enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped,
+                                                                               void (*cleanup)(void *data), void *data)
+{
+       cleaner_enumerator_t *this = malloc_thing(cleaner_enumerator_t);
+       
+       this->public.enumerate = (void*)enumerate_cleaner;
+       this->public.destroy = (void*)destroy_cleaner;
+       this->wrapped = wrapped;
+       this->cleanup = cleanup;
+       this->data = data;
+       
+       return &this->public;
+}
+
+/**
+ * enumerator for single enumerator
+ */
+typedef struct {
+       enumerator_t public;
+       void *item;
+       void (*cleanup)(void *item);
+       bool done;
+} single_enumerator_t;
+
+/**
+ * Implementation of enumerator_create_single().destroy
+ */
+static void destroy_single(single_enumerator_t *this)
+{
+       if (this->cleanup)
+       {
+               this->cleanup(this->item);
+       }
+       free(this);
+}
+
+/**
+ * Implementation of enumerator_create_single().enumerate
+ */
+static bool enumerate_single(single_enumerator_t *this, void **item)
+{
+       if (this->done)
+       {
+               return FALSE;
+       }
+       *item = this->item;
+       this->done = TRUE;
+       return TRUE;
+}
+
+/**
+ * see header
+ */
+enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item))
+{
+       single_enumerator_t *this = malloc_thing(single_enumerator_t);
+       
+       this->public.enumerate = (void*)enumerate_single;
+       this->public.destroy = (void*)destroy_single;
+       this->item = item;
+       this->cleanup = cleanup;
+       this->done = FALSE;
+       
+       return &this->public;
+}
+
index df1d78206691496ddce73f41c7fc740934eecf7e..4de2878904c267f9dc55954423b5dd4bd0345a20 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file enumerator.h
- * 
- * @brief Interface of enumerator_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 enumerator enumerator
+ * @{ @ingroup utils
  */
 
 #ifndef ENUMERATOR_H_
 #define ENUMERATOR_H_
 
-#include <library.h>
-
 typedef struct enumerator_t enumerator_t;
 
+#include <library.h>
+
 /**
- * @brief Enumerate is simpler, but more flexible than iterator.
+ * Enumerate is simpler, but more flexible than iterator.
  */
 struct enumerator_t {
 
        /**
-        * @brief Enumerate collection.
+        * Enumerate collection.
         *
         * The enumerate function takes a variable argument list containing 
         * pointers where the enumerated values get written.
@@ -44,14 +44,104 @@ struct enumerator_t {
        bool (*enumerate)(enumerator_t *this, ...);
                
        /**
-     * @brief Destroy a enumerator instance.
+     * Destroy a enumerator instance.
      */
     void (*destroy)(enumerator_t *this);
 };
 
 /**
- * @brief Create an enumerator which enumerates over nothing
+ * Create an enumerator which enumerates over nothing
+ *
+ * @return                     an enumerator over no values
  */
 enumerator_t* enumerator_create_empty();
 
-#endif /* ENUMERATOR_H_ */
+/**
+ * Create an enumerator which enumerates over a single item
+ *
+ * @param item         item to enumerate
+ * @param cleanup      cleanup function called on destroy with the item
+ * @return                     an enumerator over a single value
+ */
+enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item));
+
+/**
+ * Create an enumerator over files/subdirectories in a directory.
+ *
+ * This enumerator_t.enumerate() function returns a (to the directory) relative
+ * filename (as a char*), an absolute filename (as a char*) and a file status
+ * (to a struct stat), which all may be NULL. "." and ".." entries are
+ * skipped. Example:
+ *
+ * @code
+       char *rel, *abs;
+       struct stat st;
+       enumerator_t *e;
+       
+       e = enumerator_create_directory("/tmp");
+       if (e)
+       {
+               while (e->enumerate(e, &rel, &abs, &st))
+               {
+                       if (S_ISDIR(st.st_mode) && *rel != '.')
+                       {
+                               printf("%s\n", abs);
+                       }
+               }
+               e->destroy(e);
+       }
+   @endcode
+ *
+ * @param path         path of the directory
+ * @return                     the directory enumerator, NULL on failure
+ */
+enumerator_t* enumerator_create_directory(char *path);
+
+/**
+ * Creates an enumerator which enumerates over enumerated enumerators :-).
+ * 
+ * The variable argument list of enumeration values is limit to 5.
+ *
+ * @param outer                                        outer enumerator
+ * @param inner_constructor            constructor to inner enumerator
+ * @param data                                 data to pass to each inner_constructor call
+ * @param destroy_data                 destructor to pass to data
+ * @return                                             the nested enumerator
+ */
+enumerator_t *enumerator_create_nested(enumerator_t *outer,
+                                       enumerator_t *(inner_constructor)(void *outer, void *data),
+                                       void *data, void (*destroy_data)(void *data));
+
+/**
+ * Creates an enumerator which filters output of another enumerator.
+ *
+ * The filter function receives the user supplied "data" followed by a
+ * unfiltered enumeration item, followed by an output pointer where to write
+ * the filtered data. Then the next input/output pair follows.
+ * It returns TRUE to deliver the
+ * values to the caller of enumerate(), FALSE to filter this enumeration.
+ *
+ * The variable argument list of enumeration values is limit to 5.
+ *
+ * @param unfiltered                   unfiltered enumerator to wrap, gets destroyed
+ * @param filter                               filter function
+ * @param data                                 user data to supply to filter
+ * @param destructor                   destructor function to clean up data after use
+ * @return                                             the filtered enumerator
+ */
+enumerator_t *enumerator_create_filter(enumerator_t *unfiltered,
+                                       bool (*filter)(void *data, ...),
+                                       void *data, void (*destructor)(void *data));
+
+/**
+ * Create an enumerator wrapper which does a cleanup on destroy.
+ *
+ * @param wrapped                              wrapped enumerator
+ * @param cleanup                              cleanup function called on destroy
+ * @param data                                 user data to supply to cleanup
+ * @return                                             the enumerator with cleanup
+ */
+enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped,
+                                       void (*cleanup)(void *data), void *data);
+
+#endif /* ENUMERATOR_H_ @} */
diff --git a/src/libstrongswan/utils/fetcher.c b/src/libstrongswan/utils/fetcher.c
deleted file mode 100644 (file)
index 7a06999..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-/**
- * @file fetcher.c
- * 
- * @brief Implementation of fetcher_t.
- * 
- */
-
-/*
- * Copyright (C) 2007 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 <fetcher://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#ifdef LIBCURL
-#include <curl/curl.h>
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
-#ifndef LDAP_DEPRECATED
-#define LDAP_DEPRECATED                1
-#endif
-#include <ldap.h>
-#endif /* LIBLDAP */
-
-#include <library.h>
-#include <debug.h>
-
-#include "fetcher.h"
-
-typedef struct private_fetcher_t private_fetcher_t;
-
-/**
- * @brief Private Data of a fetcher_t object.
- */
-struct private_fetcher_t {
-       /**
-        * Public data
-        */
-       fetcher_t public;
-
-       /**
-        * URI of the information source
-        */
-       const char *uri;
-
-#ifdef LIBCURL
-       /**
-        * we use libcurl from http://curl.haxx.se/ as a fetcher
-        */
-       CURL* curl;
-#endif /* LIBCURL */
-       
-#ifdef LIBLDAP
-       /**
-        * we use libldap from http://www.openssl.org/ as a fetcher
-        */
-       LDAP *ldap;
-       LDAPURLDesc *lurl;
-#endif /* LIBLDAP */
-};
-
-/**
- * writes data into a dynamically resizeable chunk_t
- * needed for libcurl responses
- */
-static size_t curl_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;
-}
-
-/**
- * Implements fetcher_t.get for curl methods
- */
-static chunk_t curl_get(private_fetcher_t *this)
-{
-       chunk_t response = chunk_empty;
-
-#ifdef LIBCURL
-       if (this->curl)
-       {
-               CURLcode res;
-               chunk_t curl_response = chunk_empty;
-               char curl_error_buffer[CURL_ERROR_SIZE];
-
-               curl_easy_setopt(this->curl, CURLOPT_URL, this->uri);
-               curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, curl_write_buffer);
-               curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&curl_response);
-               curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, &curl_error_buffer);
-               curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
-               curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT);
-               curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
-
-               DBG1("sending curl request to '%s'...", this->uri);
-               res = curl_easy_perform(this->curl);
-
-               if (res == CURLE_OK)
-               {
-               DBG1("received valid curl response");
-                       response = chunk_clone(curl_response);
-               }
-               else
-               {
-               DBG1("curl request failed: %s", curl_error_buffer);
-               }
-               curl_free(curl_response.ptr);
-       }
-#else
-       DBG1("warning: libcurl fetching not compiled in");
-#endif  /* LIBCURL */
-       return response;
-}
-
-/**
- * Implements fetcher_t.post.
- */
-static chunk_t http_post(private_fetcher_t *this, const char *request_type, chunk_t request)
-{
-       chunk_t response = chunk_empty;
-
-#ifdef LIBCURL
-       if (this->curl)
-       {
-               CURLcode res;
-               struct curl_slist *headers = NULL;
-               chunk_t curl_response = chunk_empty;
-               char curl_error_buffer[CURL_ERROR_SIZE];
-               char content_type[BUF_LEN];
-
-               /* set content type header */
-               snprintf(content_type, BUF_LEN, "Content-Type: %s", request_type);
-               headers = curl_slist_append(headers, content_type);
-
-               /* set options */
-               curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
-               curl_easy_setopt(this->curl, CURLOPT_URL, this->uri);
-               curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, curl_write_buffer);
-               curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, (void *)&curl_response);
-               curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, request.ptr);
-               curl_easy_setopt(this->curl, CURLOPT_POSTFIELDSIZE, request.len);
-               curl_easy_setopt(this->curl, CURLOPT_ERRORBUFFER, &curl_error_buffer);
-               curl_easy_setopt(this->curl, CURLOPT_FAILONERROR, TRUE);
-               curl_easy_setopt(this->curl, CURLOPT_CONNECTTIMEOUT, FETCHER_TIMEOUT);
-               curl_easy_setopt(this->curl, CURLOPT_NOSIGNAL, TRUE);
-
-               DBG1("sending http post request to '%s'...", this->uri);
-               res = curl_easy_perform(this->curl);
-
-               if (res == CURLE_OK)
-               {
-               DBG1("received valid http response");
-                       response = chunk_clone(curl_response);
-               }
-               else
-               {
-               DBG1("http post request using libcurl failed: %s", curl_error_buffer);
-               }
-               curl_slist_free_all(headers);
-               curl_free(curl_response.ptr);
-       }
-#else
-       DBG1("warning: libcurl fetching not compiled in");
-#endif  /* LIBCURL */
-       return response;
-}
-
-#ifdef LIBLDAP
-/**
- * Parses the result returned by an ldap query
- */
-static chunk_t ldap_parse(LDAP *ldap, LDAPMessage *result)
-{
-       chunk_t response = chunk_empty;
-       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)
-               {
-                       struct berval **values = ldap_get_values_len(ldap, entry, attr);
-
-                       if (values != NULL)
-                       {
-                               if (values[0] != NULL)
-                               {
-                                       response.len = values[0]->bv_len;
-                                       response.ptr = malloc(response.len);
-                                       memcpy(response.ptr, values[0]->bv_val, response.len);
-
-                                       if (values[1] != NULL)
-                                       {
-                                               ugh = "more than one value was fetched - first selected";
-                                       }
-                               }
-                               else
-                               {
-                                       ugh = "no values in attribute";
-                               }
-                               ldap_value_free_len(values);
-                       }
-                       else
-                       {
-                               ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
-                       }
-                       ldap_memfree(attr);
-               }
-               else
-               {
-                       ugh = ldap_err2string(ldap_result2error(ldap, entry, 0));
-               }
-               ber_free(ber, 0);
-       }
-       else
-       {
-               ugh = ldap_err2string(ldap_result2error(ldap, result, 0));
-       }
-       if (ugh)
-       {
-               DBG1("ldap request failed: %s", ugh); 
-       }
-       return response;
-}
-#endif  /* LIBLDAP */
-
-/**
- * Implements fetcher_t.get for curl methods
- */
-static chunk_t ldap_get(private_fetcher_t *this)
-{
-       chunk_t response = chunk_empty;
-
-#ifdef LIBLDAP
-       if (this->ldap)
-       {
-               err_t ugh = NULL;
-               int rc;
-               int ldap_version = LDAP_VERSION3;
-
-               struct timeval timeout;
-
-               timeout.tv_sec  = FETCHER_TIMEOUT;
-               timeout.tv_usec = 0;
-
-               ldap_set_option(this->ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
-               ldap_set_option(this->ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
-
-               DBG1("sending ldap request to '%s'...", this->uri);
-
-               rc = ldap_simple_bind_s(this->ldap, NULL, NULL);
-               if (rc == LDAP_SUCCESS)
-               {
-                       LDAPMessage *result;
-
-                       timeout.tv_sec = FETCHER_TIMEOUT;
-                       timeout.tv_usec = 0;
-
-                       rc = ldap_search_st(this->ldap, this->lurl->lud_dn,
-                                                                                       this->lurl->lud_scope,
-                                                                                       this->lurl->lud_filter,
-                                                                                       this->lurl->lud_attrs,
-                                                                                       0, &timeout, &result);
-
-                       if (rc == LDAP_SUCCESS)
-                       {
-                               response = ldap_parse(this->ldap, result);
-                               if (response.ptr)
-                               {
-                               DBG1("received valid ldap response");
-                               }
-                               ldap_msgfree(result);
-                       }
-                       else
-                       {
-                               ugh = ldap_err2string(rc);
-                       }
-               }
-               else
-               {
-                       ugh = ldap_err2string(rc);
-               }
-               ldap_unbind_s(this->ldap);
-
-               if (ugh)
-               {
-                       DBG1("ldap request failed: %s", ugh);
-               }
-       }
-#else   /* !LIBLDAP */
-       DBG1("warning: libldap fetching not compiled in");
-#endif  /* !LIBLDAP */
-    return response;
-}
-
-/**
- * Implements fetcher_t.destroy
- */
-static void destroy(private_fetcher_t *this)
-{
-#ifdef LIBCURL
-       if (this->curl)
-       {
-               curl_easy_cleanup(this->curl);
-       }
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
-       if (this->lurl)
-       {
-               ldap_free_urldesc(this->lurl);
-       }
-#endif /* LIBLDAP */
-
-       free(this);
-}
-
-/*
- * Described in header.
- */
-fetcher_t *fetcher_create(const char *uri)
-{
-       private_fetcher_t *this = malloc_thing(private_fetcher_t);
-       
-       /* initialize */
-       this->uri = uri;
-
-#ifdef LIBCURL
-       this->curl = NULL;
-#endif /* LIBCURL */
-
-#ifdef LIBLDAP
-               this->lurl = NULL;
-               this->ldap = NULL;
-#endif /* LIBLDAP */
-
-       if (strlen(uri) >= 4 && strncasecmp(uri, "ldap", 4) == 0)
-       {
-#ifdef LIBLDAP
-               int rc = ldap_url_parse(uri, &this->lurl);
-
-               if (rc == LDAP_SUCCESS)
-               {
-                       this->ldap = ldap_init(this->lurl->lud_host,
-                                                                  this->lurl->lud_port);
-               }
-               else
-               {
-                       DBG1("ldap: %s", ldap_err2string(rc));
-                       this->ldap = NULL;
-               }
-#endif /* LIBLDAP */
-               this->public.get = (chunk_t (*) (fetcher_t*))ldap_get;
-       }
-       else
-       {
-#ifdef LIBCURL
-               this->curl = curl_easy_init();
-               if (this->curl == NULL)
-               {
-                       DBG1("curl_easy_init_failed()");
-               }
-#endif /* LIBCURL */
-               this->public.get = (chunk_t (*) (fetcher_t*))curl_get;
-       }
-
-       /* public functions */
-       this->public.post = (chunk_t (*) (fetcher_t*,const char*,chunk_t))http_post;
-       this->public.destroy = (void (*) (fetcher_t*))destroy;
-
-       return &this->public;
-}
-
-/**
- * Described in header.
- */
-void fetcher_initialize(void)
-{
-#ifdef LIBCURL
-       CURLcode res;
-
-       /* initialize libcurl */
-       DBG1("initializing libcurl");
-       res = curl_global_init(CURL_GLOBAL_NOTHING);
-       if (res != CURLE_OK)
-       {
-               DBG1("libcurl could not be initialized: %s", curl_easy_strerror(res));
-    }
-#endif /* LIBCURL */
-}
-
-/**
- * Described in header.
- */
-void fetcher_finalize(void)
-{
-#ifdef LIBCURL
-       /* finalize libcurl */
-       DBG1("finalizing libcurl");
-       curl_global_cleanup();
-#endif /* LIBCURL */
-}
-
diff --git a/src/libstrongswan/utils/fetcher.h b/src/libstrongswan/utils/fetcher.h
deleted file mode 100644 (file)
index 47b43a0..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file fetcher.h
- *
- * @brief Interface of fetcher_t.
- *
- */
-
-/*
- * Copyright (C) 2007 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 <fetcher://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT 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 FETCHER_H_
-#define FETCHER_H_
-
-typedef struct fetcher_t fetcher_t;
-
-#include <chunk.h>
-
-#define FETCHER_TIMEOUT        10      /* seconds */
-
-/**
- * @brief Fetches information from an URI (http, file, ftp, etc.)
- *
- * @ingroup utils
- */
-struct fetcher_t {
-
-       /**
-        * @brief Get information via a get request.
-        * 
-        * @param this                          calling object
-        * @param uri                           uri specifying the information source
-        * @return                                      chunk_t containing the information
-        */
-       chunk_t (*get) (fetcher_t *this);
-
-       /**
-        * @brief Get information via a get request.
-        * 
-        * @param this                          calling object
-        * @param uri                           uri specifying the information source
-        * @param type                          content type of http post request
-        * @param request                       binary data for http post request
-        * @return                                      chunk_t containing the information
-        */
-       chunk_t (*post) (fetcher_t *this, const char *type, chunk_t request);
-
-       /**
-        * @brief Destroys the fetcher_t object.
-        * 
-        * @param this                  fetcher_t to destroy
-        */
-       void (*destroy) (fetcher_t *this);
-
-};
-
-/**
- * @brief Create a fetcher_t object.
- * 
- * @return                     created fetcher_t object
- * 
- * @ingroup utils
- */
-fetcher_t* fetcher_create(const char *uri);
-
-/**
- * @brief Initializes the fetcher_t class
- *
- * call this function only once in the main program
- *
- * @ingroup utils
- */
-void fetcher_initialize(void);
-
-/**
- * @brief Finalizes the fetcher_t class
- *
- * call this function only once befor exiting the main program
- *
- * @ingroup utils
- */
-void fetcher_finalize(void);
-
-#endif /*FETCHER_H_*/
index 68e9c95000dd8d884f2c3a68672200c8e0413390..835544e4d186460992ee62fb77b2b1ec1924124f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file host.c
- * 
- * @brief Implementation of host_t.
- * 
- */
-
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
@@ -21,6 +14,8 @@
  * WITHOUT ANY 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>
@@ -32,7 +27,7 @@
 typedef struct private_host_t private_host_t;
 
 /**
- * @brief Private Data of a host object.
+ * Private Data of a host object.
  */
 struct private_host_t {        
        /**
@@ -155,12 +150,27 @@ static int print(FILE *stream, const struct printf_info *info,
        }
 }
 
+
 /**
- * register printf() handlers
+ * arginfo handler for printf() hosts
  */
-static void __attribute__ ((constructor))print_register()
+int arginfo(const struct printf_info *info, size_t n, int *argtypes)
 {
-       register_printf_function(PRINTF_HOST, print, arginfo_ptr);
+       if (n > 0)
+       {
+               argtypes[0] = PA_POINTER;
+       }
+       return 1;
+}
+
+/**
+ * return printf hook functions for a host
+ */
+printf_hook_functions_t host_get_printf_hooks()
+{
+       printf_hook_functions_t hooks = {print, arginfo};
+       
+       return hooks;
 }
 
 /**
index ee9aa457f4ee014efbc7e50ac115cdcd729fe08c..fd2fe01b1389167eff63f9a808e5edcefa50e776 100644 (file)
@@ -1,14 +1,7 @@
-/**
- * @file host.h
- *
- * @brief Interface of host_t.
- *
- */
-
 /*
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2006-2007 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * for more details.
  */
 
+/**
+ * @defgroup host host
+ * @{ @ingroup utils
+ */
+
 #ifndef HOST_H_
 #define HOST_H_
 
@@ -49,42 +47,31 @@ enum host_diff_t {
 };
 
 /**
- * @brief Representates a Host
+ * Representates a Host
  * 
  * Host object, identifies a address:port pair and defines some 
  * useful functions on it.
- * 
- * @b Constructors:
- * - host_create()
- * - host_create_from_chunk()
- * - host_create_from_sockaddr()
- * 
- * @todo Add IPv6 support
- * 
- * @ingroup utils
  */
 struct host_t {
        
        /** 
-        * @brief Build a clone of this host object.
+        * Build a clone of this host object.
         * 
-        * @param this                  object to clone
-        * @return                              cloned host
+        * @return              cloned host
         */
        host_t *(*clone) (host_t *this);
        
        /** 
-        * @brief Get a pointer to the internal sockaddr struct.
+        * Get a pointer to the internal sockaddr struct.
         * 
         * This is used for sending and receiving via sockets.
         * 
-        * @param this                  object to clone
-        * @return                              pointer to the internal sockaddr structure
+        * @return              pointer to the internal sockaddr structure
         */
        sockaddr_t  *(*get_sockaddr) (host_t *this);
        
        /** 
-        * @brief Get the length of the sockaddr struct.
+        * Get the length of the sockaddr struct.
         * 
         * Depending on the family, the length of the sockaddr struct
         * is different. Use this function to get the length of the sockaddr
@@ -92,140 +79,119 @@ struct host_t {
         * 
         * This is used for sending and receiving via sockets.
         * 
-        * @param this                  object to clone
-        * @return                              length of the sockaddr struct
+        * @return              length of the sockaddr struct
         */
        socklen_t *(*get_sockaddr_len) (host_t *this);
        
        /**
-        * @brief Gets the family of the address
+        * Gets the family of the address
         * 
-        * @param this                  calling object
-        * @return                              family
+        * @return              family
         */
        int (*get_family) (host_t *this);
        
        /** 
-        * @brief Checks if the ip address of host is set to default route.
+        * Checks if the ip address of host is set to default route.
         * 
-        * @param this                  calling object
-        * @return                              
-        *                                              - TRUE if host has IP 0.0.0.0 for default route 
-        *                                              - FALSE otherwise
+        * @return              TRUE if host is 0.0.0.0 or 0::0, FALSE otherwise
         */
        bool (*is_anyaddr) (host_t *this);
        
        /** 
-        * @brief get the address of this host as chunk_t
+        * Get the address of this host as chunk_t
         * 
         * Returned chunk points to internal data.
         * 
-        * @param this                  object
-        * @return                              address string, 
+        * @return              address string, 
         */
        chunk_t (*get_address) (host_t *this);
                
        /** 
-        * @brief get the port of this host
+        * Get the port of this host
         * 
-        * @param this                  object to clone
-        * @return                              port number
+        * @return              port number
         */
        u_int16_t (*get_port) (host_t *this);
 
        /** 
-        * @brief set the port of this host
+        * Set the port of this host
         *
-        * @param this                  object to clone
-        * @param port                  port numer
+        * @param port  port numer
         */
        void (*set_port) (host_t *this, u_int16_t port);
                
        /** 
-        * @brief Compare the ips of two hosts hosts.
+        * Compare the ips of two hosts hosts.
         * 
-        * @param this                  object to compare
-        * @param other                 the other to compare
-        * @return                              TRUE if addresses are equal.
+        * @param other the other to compare
+        * @return              TRUE if addresses are equal.
         */
        bool (*ip_equals) (host_t *this, host_t *other);
                
        /** 
-        * @brief Compare two hosts, with port.
+        * Compare two hosts, with port.
         * 
-        * @param this                  object to compare
-        * @param other                 the other to compare
-        * @return                              TRUE if addresses and ports are equal.
+        * @param other the other to compare
+        * @return              TRUE if addresses and ports are equal.
         */
        bool (*equals) (host_t *this, host_t *other);
 
        /** 
-        * @brief Compare two hosts and return the differences.
+        * Compare two hosts and return the differences.
         *
-        * @param this                  object to compare
-        * @param other                 the other to compare
-        * @return                              differences in a combination of host_diff_t's
+        * @param other the other to compare
+        * @return              differences in a combination of host_diff_t's
         */
        host_diff_t (*get_differences) (host_t *this, host_t *other);
        
        /** 
-        * @brief Destroy this host object
-        * 
-        * @param this                  calling
-        * @return                              SUCCESS in any case
+        * Destroy this host object.
         */
        void (*destroy) (host_t *this);
 };
 
 /**
- * @brief Constructor to create a host_t object from an address string.
+ * Constructor to create a host_t object from an address string.
  *
  * @param string               string of an address, such as "152.96.193.130"
  * @param port                 port number
- * @return                             
- *                                             - host_t object 
- *                                             - NULL, if string not an address.
- * 
- * @ingroup network
+ * @return                             host_t, NULL if string not an address.
  */
 host_t *host_create_from_string(char *string, u_int16_t port);
 
 /**
- * @brief Constructor to create a host_t object from an address chunk
+ * Constructor to create a host_t object from an address chunk
  *
- * @param family               Address family to use for this object, such as AF_INET or AF_INET6
- * @param address              address as 4 byte chunk_t in networ order
+ * @param family               Address family, such as AF_INET or AF_INET6
+ * @param address              address as chunk_t in networ order
  * @param port                 port number
- * @return                             
- *                                             - host_t object 
- *                                             - NULL, if family not supported or chunk_t length not 4 bytes.
- * 
- * @ingroup network
+ * @return                             host_t, NULL if family not supported/chunk invalid
  */
 host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port);
 
 /**
- * @brief Constructor to create a host_t object from a sockaddr struct
+ * Constructor to create a host_t object from a sockaddr struct
  *
  * @param sockaddr             sockaddr struct which contains family, address and port
- * @return                             
- *                                             - host_t object 
- *                                             - NULL, if family not supported.
- * 
- * @ingroup network
+ * @return                             host_t, NULL if family not supported
  */
 host_t *host_create_from_sockaddr(sockaddr_t *sockaddr);
 
 /**
- * @brief Create a host without an address, a "any" host.
+ * Create a host without an address, a "any" host.
  *
  * @param family               family of the any host
- * @return                             
- *                                             - host_t object 
- *                                             - NULL, if family not supported.
- * 
- * @ingroup network
+ * @return                             host_t, NULL if family not supported
  */
 host_t *host_create_any(int family);
 
-#endif /*HOST_H_*/
+/**
+ * Get printf hooks for a host.
+ *
+ * Arguments are: 
+ *    host_t *host
+ * Use #-modifier to include port number
+ */
+printf_hook_functions_t host_get_printf_hooks();
+
+#endif /* HOST_H_ @}*/
index 6d969ed16358be5adda55d9f42f0ef57c755dd7a..948472cc8c90a6f82d1a438620bc01148f785694 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file identification.c
- * 
- * @brief Implementation of identification_t. 
- * 
- */
-
 /*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -20,7 +13,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
  */
 
 #define _GNU_SOURCE
 
 #include <asn1/asn1.h>
 
+ENUM_BEGIN(id_match_names, ID_MATCH_NONE, ID_MATCH_MAX_WILDCARDS,
+       "MATCH_NONE",
+       "MATCH_ANY",
+       "MATCH_MAX_WILDCARDS");
+ENUM_NEXT(id_match_names, ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_MAX_WILDCARDS,
+       "MATCH_PERFECT");
+ENUM_END(id_match_names, ID_MATCH_PERFECT);
+
 ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
        "ID_ANY",
        "ID_IPV4_ADDR",
@@ -49,10 +50,11 @@ ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
        "ID_DER_ASN1_DN",
        "ID_DER_ASN1_GN",
        "ID_KEY_ID");
-ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_DER_ASN1_GN_URI, ID_KEY_ID,
-       "ID_DER_ASN1_GN_URI");
-ENUM_END(id_type_names, ID_DER_ASN1_GN_URI);
-
+ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_PUBKEY_SHA1, ID_KEY_ID,
+       "ID_DER_ASN1_GN_URI",
+       "ID_PUBKEY_INFO_SHA1",
+       "ID_PUBKEY_SHA1");
+ENUM_END(id_type_names, ID_PUBKEY_SHA1);
 
 /**
  * X.501 acronyms for well known object identifiers (OIDs)
@@ -237,7 +239,7 @@ static chunk_t sanitize_chunk(chunk_t chunk)
 /**
  * Pointer is set to the first RDN in a DN
  */
-static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
+static bool init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
 {
        *rdn = chunk_empty;
        *attribute = chunk_empty;
@@ -246,7 +248,7 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex
        if (*dn.ptr != ASN1_SEQUENCE)
        {
                /* DN is not a SEQUENCE */
-               return FAILED;
+               return FALSE;
        }
        
        rdn->len = asn1_length(&dn);
@@ -254,7 +256,7 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex
        if (rdn->len == ASN1_INVALID_LENGTH)
        {
                /* Invalid RDN length */
-               return FAILED;
+               return FALSE;
        }
        
        rdn->ptr = dn.ptr;
@@ -262,13 +264,13 @@ static status_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *nex
        /* are there any RDNs ? */
        *next = rdn->len > 0;
        
-       return SUCCESS;
+       return TRUE;
 }
 
 /**
  * Fetches the next RDN in a DN
  */
-static status_t 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;
 
@@ -283,13 +285,13 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
                if (*rdn->ptr != ASN1_SET)
                {
                        /* RDN is not a SET */
-                       return FAILED;
+                       return FALSE;
                }
                attribute->len = asn1_length(rdn);
                if (attribute->len == ASN1_INVALID_LENGTH)
                {
                        /* Invalid attribute length */
-                       return FAILED;
+                       return FALSE;
                }
                attribute->ptr = rdn->ptr;
                /* advance to start of next RDN */
@@ -301,7 +303,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
        if (*attribute->ptr != ASN1_SEQUENCE)
        {
                /* attributeTypeAndValue is not a SEQUENCE */
-               return FAILED;
+               return FALSE;
        }
        
        /* extract the attribute body */
@@ -310,7 +312,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
        if (body.len == ASN1_INVALID_LENGTH)
        {
                /* Invalid attribute body length */
-               return FAILED;
+               return FALSE;
        }
        
        body.ptr = attribute->ptr;
@@ -323,7 +325,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
        if (*body.ptr != ASN1_OID)
        {
                /* attributeType is not an OID */
-               return FAILED;
+               return FALSE;
        }
        /* extract OID */
        oid->len = asn1_length(&body);
@@ -331,7 +333,7 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
        if (oid->len == ASN1_INVALID_LENGTH)
        {
                /* Invalid attribute OID length */
-               return FAILED;
+               return FALSE;
        }
        oid->ptr = body.ptr;
        
@@ -348,19 +350,19 @@ static status_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, ch
        if (value->len == ASN1_INVALID_LENGTH)
        {
                /* Invalid attribute string length */
-               return FAILED;
+               return FALSE;
        }
        value->ptr = body.ptr;
        
        /* are there any RDNs left? */
        *next = rdn->len > 0 || attribute->len > 0;
-       return SUCCESS;
+       return TRUE;
 }
 
 /**
  * Parses an ASN.1 distinguished name int its OID/value pairs
  */
-static status_t dntoa(chunk_t dn, chunk_t *str)
+static bool dntoa(chunk_t dn, chunk_t *str)
 {
        chunk_t rdn, oid, attribute, value, proper;
        asn1_t type;
@@ -368,17 +370,17 @@ static status_t dntoa(chunk_t dn, chunk_t *str)
        bool next;
        bool first = TRUE;
 
-       status_t status = init_rdn(dn, &rdn, &attribute, &next);
-
-       if (status != SUCCESS)
-               return status;
+       if (!init_rdn(dn, &rdn, &attribute, &next))
+       {
+               return FALSE;
+       }
 
        while (next)
        {
-               status = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
-
-               if (status != SUCCESS)
-                       return status;
+               if (!get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next))
+               {
+                       return FALSE;
+               }
 
                if (first) 
                { /* first OID/value pair */
@@ -404,7 +406,7 @@ static status_t dntoa(chunk_t dn, chunk_t *str)
                update_chunk(str, snprintf(str->ptr,str->len,"=%.*s", (int)proper.len, proper.ptr));
                chunk_free(&proper);
        }
-       return SUCCESS;
+       return TRUE;
 }
 
 /**
@@ -420,15 +422,17 @@ static bool same_dn(chunk_t a, chunk_t b)
 
        /* same lengths for the DNs */
        if (a.len != b.len)
+       {
                return FALSE;
-
+       }
        /* try a binary comparison first */
        if (memeq(a.ptr, b.ptr, b.len))
+       {
                return TRUE;
+       }
        /* initialize DN parsing */
-       if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != SUCCESS
-       ||      init_rdn(b, &rdn_b, &attribute_b, &next_b) != SUCCESS)
+       if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) ||
+               !init_rdn(b, &rdn_b, &attribute_b, &next_b))
        {
                return FALSE;
        }
@@ -437,23 +441,27 @@ static bool same_dn(chunk_t a, chunk_t b)
        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) != SUCCESS 
-               ||  get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != SUCCESS)
+               if (!get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) || 
+                       !get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b))
                {
                        return FALSE;
                }
 
                /* OIDs must agree */
-               if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
+               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 && known_oid(oid_a) == OID_PKCS9_EMAIL)))
+               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)
                        {
@@ -470,8 +478,9 @@ static bool same_dn(chunk_t a, chunk_t b)
        }
        /* both DNs must have same number of RDNs */
        if (next_a || next_b)
+       {
                return FALSE;
-
+       }
        /* the two DNs are equal! */
        return TRUE;
 }
@@ -490,14 +499,11 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
        bool next_a, next_b;
 
        /* initialize wildcard counter */
-       if (wildcards)
-       {
-               *wildcards = 0;
-       }
+       *wildcards = 0;
 
        /* initialize DN parsing */
-       if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != SUCCESS
-       ||      init_rdn(b, &rdn_b, &attribute_b, &next_b) != SUCCESS)
+       if (!init_rdn(a, &rdn_a, &attribute_a, &next_a) ||
+               !init_rdn(b, &rdn_b, &attribute_b, &next_b))
        {
                return FALSE;
        }
@@ -506,31 +512,32 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
        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) != SUCCESS
-               ||      get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != SUCCESS)
+               if (!get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) ||
+                       !get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b))
                {
                        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 == '*')
                {
-                       if (wildcards)
-                       {
-                               (*wildcards)++;
-                       }
+                       (*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 && known_oid(oid_a) == OID_PKCS9_EMAIL)))
+               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)
                        {
@@ -550,12 +557,8 @@ bool match_dn(chunk_t a, chunk_t b, int *wildcards)
        {
                return FALSE;
        }
-
        /* the two DNs match! */
-       if (wildcards)
-       {
-               *wildcards = min(*wildcards, MAX_WILDCARDS);
-       }
+       *wildcards = min(*wildcards, ID_MATCH_ONE_WILDCARD - ID_MATCH_MAX_WILDCARDS);
        return TRUE;
 }
 
@@ -776,120 +779,107 @@ static bool equals_strcasecmp(private_identification_t *this,
 /**
  * Default implementation of identification_t.matches.
  */
-static bool matches_binary(private_identification_t *this, 
-                                                  private_identification_t *other, int *wildcards)
+static id_match_t matches_binary(private_identification_t *this, 
+                                                  private_identification_t *other)
 {
        if (other->type == ID_ANY)
        {
-               if (wildcards)
-               {
-                       *wildcards = MAX_WILDCARDS;
-               }
-               return TRUE;
+               return ID_MATCH_ANY;
        }
-       if (wildcards)
+       if (this->type == other->type && 
+               chunk_equals(this->encoded, other->encoded))
        {
-               *wildcards = 0;
+               return ID_MATCH_PERFECT;
        }
-       return this->type == other->type &&
-                                                       chunk_equals(this->encoded, other->encoded);
+       return ID_MATCH_NONE;
 }
 
 /**
  * Special implementation of identification_t.matches for ID_RFC822_ADDR/ID_FQDN.
  * Checks for a wildcard in other-string, and compares it against this-string.
  */
-static bool matches_string(private_identification_t *this,
-                                                  private_identification_t *other, int *wildcards)
+static id_match_t matches_string(private_identification_t *this,
+                                                  private_identification_t *other)
 {
        u_int len = other->encoded.len;
        
        if (other->type == ID_ANY)
        {
-               if (wildcards)
-               {
-                       *wildcards = MAX_WILDCARDS;
-               }
-               return TRUE;
+               return ID_MATCH_ANY;
        }
-       
        if (this->type != other->type)
-               return FALSE;
-
+       {
+               return ID_MATCH_NONE;
+       }
        /* try a binary comparison first */
        if (equals_binary(this, other))
        {
-               if (wildcards)
-               {
-                       *wildcards = 0;
-               }
-               return TRUE;
+               return ID_MATCH_PERFECT;
        }
-       
        if (len == 0 || this->encoded.len < len)
-               return FALSE;
+       {
+               return ID_MATCH_NONE;
+       }
 
        /* check for single wildcard at the head of the string */
        if (*other->encoded.ptr == '*')
        {
-               if (wildcards)
-               {
-                       *wildcards = 1;
-               }
-
                /* single asterisk matches any string */
                if (len-- == 1)
-                       return TRUE;
-
-               if (memeq(this->encoded.ptr + this->encoded.len - len, other->encoded.ptr + 1, len))
-                       return TRUE;
+               {       /* not better than ID_ANY */
+                       return ID_MATCH_ANY;
+               }
+               if (memeq(this->encoded.ptr + this->encoded.len - len, 
+                                 other->encoded.ptr + 1, len))
+               {
+                       return ID_MATCH_ONE_WILDCARD;
+               }
        }
-       
-       return FALSE;
+       return ID_MATCH_NONE;
 }
 
 /**
  * Special implementation of identification_t.matches for ID_ANY.
  * ANY matches only another ANY, but nothing other
  */
-static bool matches_any(private_identification_t *this,
-                                               private_identification_t *other, int *wildcards)
+static id_match_t matches_any(private_identification_t *this,
+                                                         private_identification_t *other)
 {
-       if (wildcards)
+       if (other->type == ID_ANY)
        {
-               *wildcards = 0;
+               return ID_MATCH_ANY;
        }
-       return other->type == ID_ANY;
+       return ID_MATCH_NONE;
 }
 
 /**
- * Special implementation of identification_t.matches for ID_DER_ASN1_DN.
- * ANY matches any, even ANY, thats why its there...
+ * Special implementation of identification_t.matches for ID_DER_ASN1_DN
  */
-static bool matches_dn(private_identification_t *this,
-                                          private_identification_t *other, int *wildcards)
+static id_match_t matches_dn(private_identification_t *this,
+                                                        private_identification_t *other)
 {
+       int wc;
+
        if (other->type == ID_ANY)
        {
-               if (wildcards)
-               {
-                       *wildcards = MAX_WILDCARDS;
-               }
-               return TRUE;
+               return ID_MATCH_ANY;
        }
        
        if (this->type == other->type)
        {
-               return match_dn(this->encoded, other->encoded, wildcards);
+               if (match_dn(this->encoded, other->encoded, &wc))
+               {
+                       return ID_MATCH_PERFECT - wc;
+               }
        }
-       return FALSE;
+       return ID_MATCH_NONE;
 }
 
 /**
  * output handler in printf()
  */
 static int print(FILE *stream, const struct printf_info *info,
-                                const void *const *args)
+                                                const void *const *args)
 {
        private_identification_t *this = *((private_identification_t**)(args[0]));
        char buf[BUF_LEN];
@@ -944,12 +934,14 @@ static int print(FILE *stream, const struct printf_info *info,
                        snprintf(buf, sizeof(buf), "%.*s", this->encoded.len, this->encoded.ptr);
                        /* TODO: whats returned on failure?*/
                        dntoa(this->encoded, &buf_chunk);
-                       return fprintf(stream, "%s", buf);
+                       return fprintf(stream, "\"%s\"", buf);
                }
                case ID_DER_ASN1_GN:
                        return fprintf(stream, "(ASN.1 general Name");
                case ID_KEY_ID:
-                       return fprintf(stream, "(KEY_ID)");
+               case ID_PUBKEY_INFO_SHA1:
+               case ID_PUBKEY_SHA1:
+                       return fprintf(stream, "%#B", &this->encoded);
                case ID_DER_ASN1_GN_URI:
                {
                        proper = sanitize_chunk(this->encoded);
@@ -963,11 +955,25 @@ static int print(FILE *stream, const struct printf_info *info,
 }
 
 /**
- * register printf() handlers
+ * arginfo handler
+ */
+static int arginfo(const struct printf_info *info, size_t n, int *argtypes)
+{
+       if (n > 0)
+       {
+               argtypes[0] = PA_POINTER;
+       }
+       return 1;
+}
+
+/**
+ * Get printf hook functions
  */
-static void __attribute__ ((constructor))print_register()
+printf_hook_functions_t identification_get_printf_hooks()
 {
-       register_printf_function(PRINTF_IDENTIFICATION, print, arginfo_ptr);
+       printf_hook_functions_t hook = {print, arginfo};
+       
+       return hook;
 }
 
 /**
@@ -1011,7 +1017,7 @@ static private_identification_t *identification_create(void)
        this->public.destroy = (void (*) (identification_t*))destroy;
        /* we use these as defaults, the may be overloaded for special ID types */
        this->public.equals = (bool (*) (identification_t*,identification_t*))equals_binary;
-       this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_binary;
+       this->public.matches = (id_match_t (*) (identification_t*,identification_t*))matches_binary;
        
        this->encoded = chunk_empty;
        
@@ -1041,7 +1047,7 @@ identification_t *identification_create_from_string(char *string)
                }
                this->type = ID_DER_ASN1_DN;
                this->public.equals = (bool (*) (identification_t*,identification_t*))equals_dn;
-               this->public.matches = (bool (*) (identification_t*,identification_t*,int*))matches_dn;
+               this->public.matches = (id_match_t (*) (identification_t*,identification_t*))matches_dn;
                return &this->public;
        }
        else if (strchr(string, '@') == NULL)
@@ -1054,8 +1060,8 @@ identification_t *identification_create_from_string(char *string)
                {
                        /* any ID will be accepted */
                        this->type = ID_ANY;
-                       this->public.matches = (bool (*)
-                                       (identification_t*,identification_t*,int*))matches_any;
+                       this->public.matches = (id_match_t (*)
+                                       (identification_t*,identification_t*))matches_any;
                        return &this->public;
                }
                else
@@ -1072,8 +1078,8 @@ identification_t *identification_create_from_string(char *string)
                                        this->type = ID_FQDN;
                                        this->encoded.ptr = strdup(string);
                                        this->encoded.len = strlen(string);
-                                       this->public.matches = (bool (*) 
-                                               (identification_t*,identification_t*,int*))matches_string;
+                                       this->public.matches = (id_match_t (*) 
+                                               (identification_t*,identification_t*))matches_string;
                                        this->public.equals = (bool (*)
                                                (identification_t*,identification_t*))equals_strcasecmp;
                                        return &(this->public);
@@ -1114,8 +1120,8 @@ identification_t *identification_create_from_string(char *string)
                                this->type = ID_FQDN;
                                this->encoded.ptr = strdup(string + 1);
                                this->encoded.len = strlen(string + 1);
-                               this->public.matches = (bool (*) 
-                                               (identification_t*,identification_t*,int*))matches_string;
+                               this->public.matches = (id_match_t (*) 
+                                               (identification_t*,identification_t*))matches_string;
                                this->public.equals = (bool (*)
                                                        (identification_t*,identification_t*))equals_strcasecmp;
                                return &(this->public);
@@ -1126,8 +1132,8 @@ identification_t *identification_create_from_string(char *string)
                        this->type = ID_RFC822_ADDR;
                        this->encoded.ptr = strdup(string);
                        this->encoded.len = strlen(string);
-                       this->public.matches = (bool (*) 
-                                       (identification_t*,identification_t*,int*))matches_string;
+                       this->public.matches = (id_match_t (*) 
+                                       (identification_t*,identification_t*))matches_string;
                        this->public.equals = (bool (*)
                                                (identification_t*,identification_t*))equals_strcasecmp;
                        return &(this->public);
@@ -1146,27 +1152,29 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en
        switch (type)
        {
                case ID_ANY:
-                       this->public.matches = (bool (*)
-                                       (identification_t*,identification_t*,int*))matches_any;
+                       this->public.matches = (id_match_t (*)
+                                       (identification_t*,identification_t*))matches_any;
                        break;
                case ID_FQDN:
                case ID_RFC822_ADDR:
-                       this->public.matches = (bool (*)
-                                       (identification_t*,identification_t*,int*))matches_string;
+                       this->public.matches = (id_match_t (*)
+                                       (identification_t*,identification_t*))matches_string;
                        this->public.equals = (bool (*)
                                                (identification_t*,identification_t*))equals_strcasecmp;
                        break;
                case ID_DER_ASN1_DN:
                        this->public.equals = (bool (*)
                                        (identification_t*,identification_t*))equals_dn;
-                       this->public.matches = (bool (*)
-                                       (identification_t*,identification_t*,int*))matches_dn;
+                       this->public.matches = (id_match_t (*)
+                                       (identification_t*,identification_t*))matches_dn;
                        break;
                case ID_IPV4_ADDR:
                case ID_IPV6_ADDR:
                case ID_DER_ASN1_GN:
                case ID_KEY_ID:
                case ID_DER_ASN1_GN_URI:
+               case ID_PUBKEY_INFO_SHA1:
+               case ID_PUBKEY_SHA1:
                default:
                        break;
        }
index 59c568eaf8e03b0bdce3635ce5e56305689cad2f..31c49c2692e07b3b6845797e1f095d8de34b3c2e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file identification.h
- *
- * @brief Interface of identification_t.
- *
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 identification identification
+ * @{ @ingroup utils
  */
 
 
 
 typedef enum id_type_t id_type_t;
 typedef struct identification_t identification_t;
+typedef enum id_match_t id_match_t;
 
 #include <library.h>
 
-#define MAX_WILDCARDS     14
+/** 
+ * Matches returned from identification_t.match
+ */
+enum id_match_t {
+       /* no match */
+       ID_MATCH_NONE = 0,
+       /* match to %any ID */
+       ID_MATCH_ANY = 1,
+       /* match with maximum allowed wildcards */
+       ID_MATCH_MAX_WILDCARDS = 2,
+       /* match with only one wildcard */
+       ID_MATCH_ONE_WILDCARD = 19,
+       /* perfect match, won't get better */
+       ID_MATCH_PERFECT = 20,
+};
 
 /**
- * @brief ID Types in a ID payload.
- *
- * @ingroup utils
+ * enum names for id_match_t.
+ */
+extern enum_name_t *id_match_names;
+
+/**
+ * ID Types in a ID payload.
  */
 enum id_type_t {
 
@@ -109,7 +127,16 @@ enum id_type_t {
         * private type which represents a GeneralName of type URI
         */
        ID_DER_ASN1_GN_URI = 201,
-
+       
+       /**
+        * SHA1 hash over PKCS#1 subjectPublicKeyInfo
+        */
+       ID_PUBKEY_INFO_SHA1,
+       
+       /**
+        * SHA1 hash over PKCS#1 subjectPublicKey
+        */
+       ID_PUBKEY_SHA1,
 };
 
 /**
@@ -118,110 +145,84 @@ enum id_type_t {
 extern enum_name_t *id_type_names;
 
 /**
- * @brief Generic identification, such as used in ID payload.
- * 
- * The following types are possible:
- * - ID_IPV4_ADDR
- * - ID_FQDN
- * - ID_RFC822_ADDR
- * - ID_IPV6_ADDR
- * - ID_DER_ASN1_DN
- * - ID_DER_ASN1_GN
- * - ID_KEY_ID
- * - ID_DER_ASN1_GN_URI
- * 
- * @b Constructors:
- * - identification_create_from_string()
- * - identification_create_from_encoding()
+ * Generic identification, such as used in ID payload.
  * 
  * @todo Support for ID_DER_ASN1_GN is minimal right now. Comparison
  * between them and ID_IPV4_ADDR/RFC822_ADDR would be nice.
- *
- * @ingroup utils
  */
 struct identification_t {
        
        /**
-        * @brief Get the encoding of this id, to send over
+        * Get the encoding of this id, to send over
         * the network.
         * 
-        * @warning Result points to internal data, do NOT free!
+        * Result points to internal data, do not free.
         * 
-        * @param this          the identification_t object
         * @return                      a chunk containing the encoded bytes
         */
        chunk_t (*get_encoding) (identification_t *this);
        
        /**
-        * @brief Get the type of this identification.
+        * Get the type of this identification.
         * 
-        * @param this          the identification_t object
         * @return                      id_type_t
         */
        id_type_t (*get_type) (identification_t *this);
        
        /**
-        * @brief Check if two identification_t objects are equal.
+        * Check if two identification_t objects are equal.
         * 
-        * @param this          the identification_t object
         * @param other         other identification_t object
         * @return                      TRUE if the IDs are equal
         */
        bool (*equals) (identification_t *this, identification_t *other);
        
        /**
-        * @brief Check if an ID matches a wildcard ID.
+        * Check if an ID matches a wildcard ID.
         * 
         * An identification_t may contain wildcards, such as
         * *@strongswan.org. This call checks if a given ID
         * (e.g. tester@strongswan.org) belongs to a such wildcard
-        * ID. Returns TRUE if
+        * ID. Returns > 0 if
         * - IDs are identical
         * - other is of type ID_ANY
         * - other contains a wildcard and matches this
+        *
+        * The larger the return value is, the better is the match. Zero means
+        * no match at all, 1 means a bad match, and 2 a slightly better match.
         * 
-        * @param this          the ID without wildcard
-        * @param other         the ID containing a wildcard
+        * @param other         the ID containing one or more wildcards
         * @param wildcards     returns the number of wildcards, may be NULL
-        * @return                      TRUE if match is found
+        * @return                      match value as described above
         */
-       bool (*matches) (identification_t *this, identification_t *other, int *wildcards);
+       id_match_t (*matches) (identification_t *this, identification_t *other);
        
        /**
-        * @brief Check if an ID is a wildcard ID.
+        * Check if an ID is a wildcard ID.
         *
         * If the ID represents multiple IDs (with wildcards, or
         * as the type ID_ANY), TRUE is returned. If it is unique,
         * FALSE is returned.
         * 
-        * @param this          identification_t object
         * @return                      TRUE if ID contains wildcards
         */
        bool (*contains_wildcards) (identification_t *this);
        
        /**
-        * @brief Clone a identification_t instance.
+        * Clone a identification_t instance.
         * 
-        * @param this          the identification_t object to clone
         * @return                      clone of this
         */
        identification_t *(*clone) (identification_t *this);
 
        /**
-        * @brief Destroys a identification_t object.
-        *
-        * @param this          identification_t object
+        * Destroys a identification_t object.
         */
        void (*destroy) (identification_t *this);
 };
 
 /**
- * @brief Creates an identification_t object from a string.
- * 
- * @param string       input string, which will be converted
- * @return
- *                                     - created identification_t object, or
- *                                     - NULL if unsupported string supplied.
+ * Creates an identification_t object from a string.
  *
  * The input string may be e.g. one of the following:
  * - ID_IPV4_ADDR:             192.168.0.1
@@ -239,23 +240,29 @@ struct identification_t {
  * ND, UID, DC, CN, S, SN, serialNumber, C, L, ST, O, OU, T, D,
  * N, G, I, ID, EN, EmployeeNumber, E, Email, emailAddress, UN, 
  * unstructuredName, TCGID.
- *
- * @ingroup utils
+ * 
+ * @param string       input string, which will be converted
+ * @return                     created identification_t, NULL if not supported.
  */
 identification_t * identification_create_from_string(char *string);
 
 /**
- * @brief Creates an identification_t object from an encoded chunk.
- * 
- * @param type         type of this id, such as ID_IPV4_ADDR
- * @param encoded      encoded bytes, such as from identification_t.get_encoding
- * @return                     identification_t object
+ * 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.
- *
- * @ingroup utils
+ * 
+ * @param type         type of this id, such as ID_IPV4_ADDR
+ * @param encoded      encoded bytes, such as from identification_t.get_encoding
+ * @return                     identification_t
  */
 identification_t * identification_create_from_encoding(id_type_t type, chunk_t encoded);
 
-#endif /* IDENTIFICATION_H_ */
+/**
+ * Get the printf hook functions.
+ * 
+ * @return                     printf hook functions
+ */
+printf_hook_functions_t identification_get_printf_hooks();
+
+#endif /* IDENTIFICATION_H_ @} */
index b4ff85bfbb4ccda2fa4a922c83bfd64c41f33f03..4b845d74039d71d0678f7ee781db10740baf641d 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file iterator.h
- * 
- * @brief Interface iterator_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 iterator iterator
+ * @{ @ingroup utils
  */
 
 #ifndef ITERATOR_H_
 typedef enum hook_result_t hook_result_t;
 
 /**
- * @brief Return value of an iterator hook.
+ * Return value of an iterator hook.
  *
  * Returning HOOK_AGAIN is useful to "inject" additional elements in an
  * iteration, HOOK_NEXT is the normal iterator behavior, and HOOK_SKIP may
  * be used to filter elements out.
- *
- * @ingroup utils
  */
 enum hook_result_t {
 
@@ -56,14 +54,12 @@ enum hook_result_t {
 };
 
 /**
- * @brief Iterator hook function prototype.
+ * Iterator hook function prototype.
  *
  * @param param                user supplied parameter
  * @param in           the value the hook receives from the iterator
  * @param out          the value supplied as a result to the iterator
  * @return                     a hook_result_t
- *
- * @ingroup utils
  */
 typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out);
 
@@ -71,44 +67,34 @@ typedef hook_result_t (iterator_hook_t)(void *param, void *in, void **out);
 typedef struct iterator_t iterator_t;
 
 /**
- * @brief Iterator interface, allows iteration over collections.
+ * Iterator interface, allows iteration over collections.
  *
  * iterator_t defines an interface for iterating over collections.
  * It allows searching, deleting, updating and inserting.
  *
- * @b Constructors:
- * - via linked_list_t.create_iterator, or
- * - any other class which supports the iterator_t interface
- *
- * @see linked_list_t
- *
- * @ingroup utils 
+ * @deprecated Use enumerator instead.
  */
 struct iterator_t {
 
        /**
-        * @brief Return number of list items.
+        * Return number of list items.
         * 
-        * @param this                  calling object
         * @return                              number of list items
         */
        int (*get_count) (iterator_t *this);
        
        /**
-        * @brief Iterate over all items.
+        * Iterate over all items.
         * 
         * The easy way to iterate over items.
         * 
-        * @param this                  calling object
-        * @param[out] value    item
-        * @return
-        *                                              - TRUE, if there was an element available,
-        *                                              - FALSE otherwise
+        * @param value         item
+        * @return                      TRUE, if there was an element available, FALSE otherwise
         */
        bool (*iterate) (iterator_t *this, void** value);
        
        /**
-        * @brief Hook a function into the iterator.
+        * Hook a function into the iterator.
         *
         * Sometimes it is useful to hook in an iterator. The hook function is
         * called before any successful return of iterate(). It takes the
@@ -119,80 +105,67 @@ struct iterator_t {
         * If an iterator is hooked, only the iterate() method is valid,
         * all other methods behave undefined.
         * 
-        * @param this                  calling object
-        * @param hook                  iterator hook which manipulates the iterated value
-        * @param param                 user supplied parameter to pass back to the hook
+        * @param hook          iterator hook which manipulates the iterated value
+        * @param param         user supplied parameter to pass back to the hook
         */
        void (*set_iterator_hook) (iterator_t *this, iterator_hook_t *hook,
                                                           void *param);
        
        /**
-        * @brief Inserts a new item before the given iterator position.
+        * Inserts a new item before the given iterator position.
         * 
         * The iterator position is not changed after inserting
         * 
-        * @param this                  calling iterator
-        * @param[in] item              value to insert in list
+        * @param item          value to insert in list
         */
        void (*insert_before) (iterator_t *this, void *item);
 
        /**
-        * @brief Inserts a new item after the given iterator position.
+        * Inserts a new item after the given iterator position.
         * 
         * The iterator position is not changed after inserting.
         * 
-        * @param this                  calling iterator
-        * @param[in] item              value to insert in list
+        * @param this          calling iterator
+        * @param item          value to insert in list
         */
        void (*insert_after) (iterator_t *this, void *item);
        
        /**
-        * @brief Replace the current item at current iterator position.
+        * Replace the current item at current iterator position.
         * 
         * The iterator position is not changed after replacing.
         * 
-        * @param this                  calling iterator
-        * @param[out] old_item old value will be written here(can be NULL)
-        * @param[in] new_item  new value
-        * 
-        * @return 
-        *                                              - SUCCESS
-        *                                              - FAILED if iterator is on an invalid position
+        * @param this          calling iterator
+        * @param old           old value will be written here(can be NULL)
+        * @param new           new value
+        * @return                      SUCCESS, FAILED if iterator is on an invalid position
         */
-       status_t (*replace) (iterator_t *this, void **old_item, void *new_item);
+       status_t (*replace) (iterator_t *this, void **old, void *new);
 
        /**
-        * @brief Removes an element from list at the given iterator position.
+        * Removes an element from list at the given iterator position.
         * 
         * The iterator is set the the following position:
         * - to the item before, if available
         * - it gets reseted, otherwise
         * 
-        * @param this                  calling object
-        * @return 
-        *                                              - SUCCESS
-        *                                              - FAILED if iterator is on an invalid position
+        * @return                              SUCCESS, FAILED if iterator is on an invalid position
         */
        status_t (*remove) (iterator_t *this);
        
        /**
-        * @brief Resets the iterator position.
+        * Resets the iterator position.
         * 
         * After reset, the iterator_t objects doesn't point to an element.
         * A call to iterator_t.has_next is necessary to do any other operations
         * with the resetted iterator.
-        * 
-        * @param this                  calling object
         */
        void (*reset) (iterator_t *this);
 
        /**
-        * @brief Destroys an iterator.
-        * 
-        * @param this                  iterator to destroy
-        * 
+        * Destroys an iterator.
         */
        void (*destroy) (iterator_t *this);
 };
 
-#endif /*ITERATOR_H_*/
+#endif /*ITERATOR_H_ @} */
index dab18fd5c09866d8f6c8b83f9526d1379e2cf73b..149456875382c2651de3f66ee95e3b348a4d4479 100644 (file)
@@ -1,11 +1,5 @@
-/**
- * @file leak_detective.c
- * 
- * @brief Allocation hooks to find memory leaks.
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
+ *
+ * $Id$
  */
 
+#ifdef HAVE_DLADDR
+# define _GNU_SOURCE
+# include <dlfcn.h>
+#endif /* HAVE_DLADDR */
+       
 #include <stddef.h>
 #include <string.h>
 #include <stdio.h>
@@ -33,6 +34,7 @@
 #include <pthread.h>
 #include <netdb.h>
 #include <printf.h>
+#include <locale.h>
 #ifdef HAVE_BACKTRACE
 # include <execinfo.h>
 #endif /* HAVE_BACKTRACE */
 #include <library.h>
 #include <debug.h>
 
-#ifdef LEAK_DETECTIVE
+typedef struct private_leak_detective_t private_leak_detective_t;
+
+/**
+ * private data of leak_detective
+ */
+struct private_leak_detective_t {
+
+       /**
+        * public functions
+        */
+       leak_detective_t public;
+};
 
 /**
  * Magic value which helps to detect memory corruption. Yummy!
@@ -146,77 +159,103 @@ static void log_stack_frames(void **stack_frames, int stack_frame_count)
        char **strings;
        size_t i;
 
-       strings = backtrace_symbols (stack_frames, stack_frame_count);
+       strings = backtrace_symbols(stack_frames, stack_frame_count);
 
-       DBG1("  dumping %d stack frame addresses", stack_frame_count);
+       fprintf(stderr, " dumping %d stack frame addresses\n", stack_frame_count);
 
        for (i = 0; i < stack_frame_count; i++)
        {
-               DBG1("    %s", strings[i]);
+#ifdef HAVE_DLADDR
+               Dl_info info;
+               
+               /* TODO: this is quite hackish, but it works. A more proper solution
+                * would execve addr2strongline and pipe the output to DBG1() */
+               if (dladdr(stack_frames[i], &info))
+               {
+                       char cmd[1024];
+                       void *ptr = stack_frames[i];
+                       
+                       if (strstr(info.dli_fname, ".so"))
+                       {
+                               ptr = (void*)(stack_frames[i] - info.dli_fbase);
+                       }
+                       snprintf(cmd, sizeof(cmd), "addr2line -e %s %p", info.dli_fname, ptr);
+                       if (info.dli_sname)
+                       {
+                               fprintf(stderr, "  \e[33m%s\e[0m @ %p (\e[31m%s+0x%x\e[0m) [%p]\n",
+                                               info.dli_fname, info.dli_fbase, info.dli_sname,
+                                               stack_frames[i] - info.dli_saddr, stack_frames[i]);
+                       }
+                       else
+                       {
+                               fprintf(stderr, "  \e[33m%s\e[0m @ %p [%p]\n", info.dli_fname,
+                                               info.dli_fbase, stack_frames[i]);
+                       }
+                       fprintf(stderr, "    -> \e[32m");
+                       system(cmd);
+                       fprintf(stderr, "\e[0m");
+               }
+               else
+#endif /* HAVE_DLADDR */
+               {
+                       fprintf(stderr, "    %s\n", strings[i]);
+               }
        }
        free (strings);
 #endif /* HAVE_BACKTRACE */
 }
 
 /**
- * Whitelist, which contains address ranges in stack frames ignored when leaking.
- * 
- * This is necessary, as some function use allocation hacks (static buffers)
- * and so on, which we want to suppress on leak reports.
+ * Leak report white list
  *
- * The range_size is calculated using the readelf utility, e.g.:
- * readelf -s /lib/glibc.so.6
- * The values are for glibc-2.4 and may or may not be correct on other systems.
+ * List of functions using static allocation buffers or should be suppressed
+ * otherwise on leak report. 
  */
-typedef struct whitelist_t whitelist_t;
-
-struct whitelist_t {
-       void* range_start;
-       size_t range_size;
-};
-
-#ifdef LIBCURL
-/* dummy declaration for whitelisting */
-void *Curl_getaddrinfo(void);
-#endif /* LIBCURL */
-
-whitelist_t whitelist[] = {
-       {pthread_create,                        2542},
-       {pthread_setspecific,            217},
-       {mktime,                                          60},
-       {tzset,                                          123},
-       {inet_ntoa,                                      249},
-       {strerror,                                       180},
-       {getprotobynumber,                       291},
-       {getservbyport,                          311},
-       {register_printf_function,       159},
-       {syslog,                                          44},
-       {vsyslog,                                         41},
-       {dlopen,                                         109},
-#      ifdef LIBCURL
-       /* from /usr/lib/libcurl.so.3 */
-       {Curl_getaddrinfo,                       480},
-#      endif /* LIBCURL */
+char *whitelist[] = {
+       "pthread_create",
+       "pthread_setspecific",
+       "mktime",
+       "tzset",
+       "inet_ntoa",
+       "strerror",
+       "getprotobynumber",
+       "getservbyport",
+       "getservbyname",
+       "register_printf_function",
+       "syslog",
+       "vsyslog",
+       "dlopen",
+       "getaddrinfo",
+       "setlocale",
+       "mysql_init_character_set",
+       "init_client_errs",
+       "my_thread_init",
 };
 
 /**
- * Check if this stack frame is whitelisted.
+ * check if a stack frame contains functions listed above
  */
 static bool is_whitelisted(void **stack_frames, int stack_frame_count)
 {
        int i, j;
        
+#ifdef HAVE_DLADDR
        for (i=0; i< stack_frame_count; i++)
        {
-               for (j=0; j<sizeof(whitelist)/sizeof(whitelist_t); j++)
-               {
-                       if (stack_frames[i] >= whitelist[j].range_start &&
-                               stack_frames[i] <= (whitelist[j].range_start + whitelist[j].range_size))
+               Dl_info info;
+               
+               if (dladdr(stack_frames[i], &info) && info.dli_sname)
+               {       
+                       for (j = 0; j < sizeof(whitelist)/sizeof(char*); j++)
                        {
-                               return TRUE;
+                               if (streq(info.dli_sname, whitelist[j]))
+                               {
+                                       return TRUE;
+                               }
                        }
                }
        }
+#endif /* HAVE_DLADDR */
        return FALSE;
 }
 
@@ -232,8 +271,9 @@ void report_leaks()
        {
                if (!is_whitelisted(hdr->stack_frames, hdr->stack_frame_count))
                {
-                       DBG1("Leak (%d bytes at %p):", hdr->bytes, hdr + 1);
-                       log_stack_frames(hdr->stack_frames, hdr->stack_frame_count);
+                       fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1);
+                       /* skip the first frame, contains leak detective logic */
+                       log_stack_frames(hdr->stack_frames + 1, hdr->stack_frame_count - 1);
                        leaks++;
                }
        }
@@ -241,13 +281,13 @@ void report_leaks()
        switch (leaks)
        {
                case 0:
-                       DBG1("No leaks detected");
+                       fprintf(stderr, "No leaks detected\n");
                        break;
                case 1:
-                       DBG1("One leak detected");
+                       fprintf(stderr, "One leak detected\n");
                        break;
                default:
-                       DBG1("%d leaks detected", leaks);
+                       fprintf(stderr, "%d leaks detected\n", leaks);
                        break;
        }
 }
@@ -334,8 +374,8 @@ void free_hook(void *ptr, const void *caller)
        uninstall_hooks();
        if (hdr->magic != MEMORY_HEADER_MAGIC)
        {
-               DBG1("freeing of invalid memory (%p, MAGIC 0x%x != 0x%x):",
-                        ptr, hdr->magic, MEMORY_HEADER_MAGIC);
+               fprintf(stderr, "freeing of invalid memory (%p, MAGIC 0x%x != 0x%x):\n",
+                               ptr, hdr->magic, MEMORY_HEADER_MAGIC);
                stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT);
                log_stack_frames(stack_frames, stack_frame_count);
                install_hooks();
@@ -380,7 +420,7 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
        uninstall_hooks();
        if (hdr->magic != MEMORY_HEADER_MAGIC)
        {
-               DBG1("reallocation of invalid memory (%p):", old);
+               fprintf(stderr, "reallocation of invalid memory (%p):\n", old);
                stack_frame_count = backtrace(stack_frames, STACK_FRAMES_COUNT);
                log_stack_frames(stack_frames, stack_frame_count);
                install_hooks();
@@ -407,65 +447,31 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
 }
 
 /**
- * Setup leak detective
+ * Implementation of leak_detective_t.destroy
  */
-void __attribute__ ((constructor)) leak_detective_init()
+static void destroy(private_leak_detective_t *this)
 {
-       if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
-       {
-               install_hooks();
-       }
-}
-
-/**
- * Clean up leak detective
- */
-void __attribute__ ((destructor)) leak_detective_cleanup()
-{
-       if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
+       if (installed)
        {
                uninstall_hooks();
                report_leaks();
        }
+       free(this);
 }
 
-/**
- * Log memory allocation statistics
+/*
+ * see header file
  */
-void leak_detective_status(FILE *stream)
+leak_detective_t *leak_detective_create()
 {
-       u_int blocks = 0;
-       size_t bytes = 0;
-       memory_header_t *hdr = &first_header;
+       private_leak_detective_t *this = malloc_thing(private_leak_detective_t);
        
-       if (getenv("LEAK_DETECTIVE_DISABLE"))
-       {
-               return;
-       }
+       this->public.destroy = (void(*)(leak_detective_t*))destroy;
        
-       pthread_mutex_lock(&mutex);
-       while ((hdr = hdr->next))
+       if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
        {
-               blocks++;
-               bytes += hdr->bytes;
+               install_hooks();
        }
-       pthread_mutex_unlock(&mutex);
-       
-       fprintf(stream, "allocation statistics:\n");
-       fprintf(stream, "  call stats: malloc: %d, free: %d, realloc: %d\n",
-                       count_malloc, count_free, count_realloc);
-       fprintf(stream, "  allocated %d blocks, total size %d bytes (avg. %d bytes)\n",
-                       blocks, bytes, bytes/blocks);
-}
-
-#else /* !LEAK_DETECTION */
-
-/**
- * Dummy when !using LEAK_DETECTIVE
- */
-void leak_detective_status(FILE *stream)
-{
-
+       return &this->public;
 }
 
-#endif /* LEAK_DETECTION */
index d4016b06ee07616182083f3e860a939e0b854d89..7638147261a436cc2d8e3631058233b281fe4ebb 100644 (file)
@@ -1,11 +1,5 @@
-/**
- * @file leak_detective.h
- * 
- * @brief malloc/free hooks to detect leaks.
- */
-
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * for more details.
  */
 
+/**
+ * @defgroup leak_detective leak_detective
+ * @{ @ingroup utils
+ */
+
 #ifndef LEAK_DETECTIVE_H_
 #define LEAK_DETECTIVE_H_
 
 /**
- * Log status information about allocation
+ * Maximum depth stack frames to register
  */
-void leak_detective_status(FILE *stream);
+#define STACK_FRAMES_COUNT 20
+
+typedef struct leak_detective_t leak_detective_t;
 
 /**
- * Max number of stack frames to include in a backtrace.
+ * Leak detective finds leaks and bad frees using malloc hooks.
+ *
+ * Currently leaks are reported to stderr on destruction.
+ *
+ * @todo Build an API for leak detective, allowing leak enumeration, statistics
+ * and dynamic whitelisting.
+ */
+struct leak_detective_t {
+               
+       /**
+     * Destroy a leak_detective instance.
+     */
+    void (*destroy)(leak_detective_t *this);
+};
+
+/**
+ * Create a leak_detective instance.
  */
-#define STACK_FRAMES_COUNT 30
+leak_detective_t *leak_detective_create();
+
+#endif /* LEAK_DETECTIVE_H_ @}*/
 
-#endif /* LEAK_DETECTIVE_H_ */
index 35ba0d7a6cc9a9163adcaf0fa272e85056f49272..c235769719ba5db170bab969db99a7527813faca 100644 (file)
@@ -1,12 +1,5 @@
-/**
- * @file lexparser.c
- * 
- * @brief lexical parser for text-based configuration files
- *  
- */
-
 /*
- * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2001-2006 Andreas Steffen
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -18,7 +11,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
  */
 
 /* memrchr is a GNU extension */
index db89ae2d2d45f36df99306dd6c0c7529f886f5b8..1c0a9997a0504b660b19fae02e41aacccca5090b 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file lexparser.h
- * 
- * @brief lexical parser for text-based configuration files
- *  
- */
-
 /*
  * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
  *
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
  */
+/**
+ * @defgroup lexparser lexparser
+ * @{ @ingroup utils
+ */
+
+#ifndef LEXPARSER_H_
+#define LEXPARSER_H_
 
 #include <library.h>
 
 /**
- * @brief Eats whitespace
+ * Eats whitespace
  */
 bool eat_whitespace(chunk_t *src);
 
 /**
- * @brief Compare null-terminated pattern with chunk
+ * Compare null-terminated pattern with chunk
  */
 bool match(const char *pattern, const chunk_t *ch);
 
 /**
- * @brief Extracts a token ending with the first occurence a given termination symbol
+ * Extracts a token ending with the first occurence a given termination symbol
  */
 bool extract_token(chunk_t *token, const char termination, chunk_t *src);
 
 /**
- * @brief Extracts a token ending with the last occurence a given termination symbol
+ * Extracts a token ending with the last occurence a given termination symbol
  */
 bool extract_last_token(chunk_t *token, const char termination, chunk_t *src);
 
 /**
- *  @brief Fetches a new text line terminated by \n or \r\n
+ *  Fetches a new text line terminated by \n or \r\n
  */
 bool fetchline(chunk_t *src, chunk_t *line);
 
 /**
- * @brief Extracts a value that might be single or double quoted
+ * Extracts a value that might be single or double quoted
  */
 err_t extract_value(chunk_t *value, chunk_t *line);
 
 /**
- * @brief extracts a name: value pair from a text line
+ * extracts a name: value pair from a text line
  */
 err_t extract_name_value(chunk_t *name, chunk_t *value, chunk_t *line);
 
 /**
- * @brief extracts a parameter: value from a text line
+ * extracts a parameter: value from a text line
  */
 err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line);
+
+#endif /* LEXPARSER_H_ @} */
index 63e1bcfbf2a8ac7fde2d4a5fa24a838649881797..16913b934771971e875dac4217e944144a6cbe5e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file linked_list.c
- *
- * @brief Implementation of linked_list_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
@@ -20,6 +13,8 @@
  * WITHOUT ANY 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>
@@ -157,6 +152,11 @@ struct private_enumerator_t {
         * next item to enumerate
         */
        element_t *next;
+       
+       /**
+        * current item
+        */
+       element_t *current;
 };
 
 /**
@@ -169,6 +169,7 @@ static bool enumerate(private_enumerator_t *this, void **item)
                return FALSE;
        }
        *item = this->next->value;
+       this->current = this->next;
        this->next = this->next->next;
        return TRUE;
 }
@@ -183,6 +184,7 @@ static enumerator_t* create_enumerator(private_linked_list_t *this)
        enumerator->enumerator.enumerate = (void*)enumerate;
        enumerator->enumerator.destroy = (void*)free;
        enumerator->next = this->first;
+       enumerator->current = NULL;
        
        return &enumerator->enumerator;
 }
@@ -459,34 +461,37 @@ static void insert_first(private_linked_list_t *this, void *item)
 }
 
 /**
- * Implementation of linked_list_t.remove_first.
+ * unlink an element form the list, returns following element
  */
-static status_t remove_first(private_linked_list_t *this, void **item)
+static element_t* remove_element(private_linked_list_t *this, element_t *element)
 {
-       element_t *element = this->first;
-       
-       if (element == NULL)
+       element_t *next, *previous;
+
+       next = element->next;
+       previous = element->previous;
+       free(element);
+       if (next) 
        {
-               return NOT_FOUND;
+               next->previous = previous;
        }
-       if (element->next != NULL)
+       else
        {
-               element->next->previous = NULL;
+               this->last = previous;
        }
-       this->first = element->next;
-       
-       if (item != NULL)
+       if (previous)
+       {
+               previous->next = next;
+       }
+       else
        {
-               *item = element->value;
+               this->first = next;
        }
        if (--this->count == 0)
        {
+               this->first = NULL;
                this->last = NULL;
        }
-       
-       free(element);
-       
-       return SUCCESS;
+       return next;
 }
 
 /**
@@ -502,6 +507,19 @@ static status_t get_first(private_linked_list_t *this, void **item)
        return SUCCESS;
 }
 
+/**
+ * Implementation of linked_list_t.remove_first.
+ */
+static status_t remove_first(private_linked_list_t *this, void **item)
+{
+       if (get_first(this, item) == SUCCESS)
+       {
+               remove_element(this, this->first);
+               return SUCCESS;
+       }
+       return NOT_FOUND;
+}
+
 /**
  * Implementation of linked_list_t.insert_last.
  */
@@ -529,151 +547,67 @@ static void insert_last(private_linked_list_t *this, void *item)
 }
 
 /**
- * Implementation of linked_list_t.remove_last.
+ * Implementation of linked_list_t.get_last.
  */
-static status_t remove_last(private_linked_list_t *this, void **item)
+static status_t get_last(private_linked_list_t *this, void **item)
 {
-       element_t *element = this->last;
-       
-       if (element == NULL)
+       if (this->count == 0)
        {
                return NOT_FOUND;
        }
-       if (element->previous != NULL)
-       {
-               element->previous->next = NULL;
-       }
-       this->last = element->previous;
-       
-       if (item != NULL)
-       {
-               *item = element->value;
-       }
-       if (--this->count == 0)
-       {
-               this->first = NULL;
-       }
-       
-       free(element);
-       
+       *item = this->last->value;
        return SUCCESS;
 }
 
 /**
- * Implementation of linked_list_t.insert_at_position.
+ * Implementation of linked_list_t.remove_last.
  */
-static status_t insert_at_position (private_linked_list_t *this,size_t position, void *item)
+static status_t remove_last(private_linked_list_t *this, void **item)
 {
-       element_t *current_element;
-       int i;
-       
-       if (this->count <= position)
-       {
-               return INVALID_ARG;
-       }
-       
-       current_element =  this->first;
-       
-       for (i = 0; i < position;i++)
+       if (get_last(this, item) == SUCCESS)
        {
-               current_element = current_element->next;
-       }
-       
-       if (current_element == NULL)
-       {
-               this->public.insert_last(&(this->public),item);
+               remove_element(this, this->last);
                return SUCCESS;
        }
-       
-       element_t *element = element_create(item);
-       if (current_element->previous == NULL)
-       {
-               current_element->previous = element;
-               element->next = current_element;
-               this->first = element;
-       }
-       else
-       {
-               current_element->previous->next = element;
-               element->previous = current_element->previous;
-               current_element->previous = element;
-               element->next = current_element;
-       }
-
-
-       this->count++;
-       return SUCCESS;
+       return NOT_FOUND;
 }
        
 /**
- * Implementation of linked_list_t.remove_at_position.
+ * Implementation of linked_list_t.remove.
  */
-static status_t remove_at_position(private_linked_list_t *this,size_t position, void **item)
+static int remove(private_linked_list_t *this, void *item,
+                                 bool (*compare)(void *,void*))
 {
-       iterator_t *iterator;
-       int i;
-       
-       if (this->count <= position)
-       {
-               return INVALID_ARG;
-       }
+       element_t *current = this->first;
+       int removed = 0;
        
-       iterator = this->public.create_iterator(&(this->public),TRUE);
-       iterator->iterate(iterator, item);
-       for (i = 0; i < position; i++)
+       while (current)
        {
-               if (!iterator->iterate(iterator, item))
+               if ((compare && compare(current->value, item)) ||
+                       (!compare && current->value == item))
                {
-                       iterator->destroy(iterator);
-                       return INVALID_ARG;
+                       removed++;
+                       current = remove_element(this, current);
                }
-       }
-       iterator->remove(iterator);
-       iterator->destroy(iterator);
-       
-       return SUCCESS;
-}
-
-/**
- * Implementation of linked_list_t.get_at_position.
- */
-static status_t get_at_position(private_linked_list_t *this,size_t position, void **item)
-{
-       int i;
-       iterator_t *iterator;
-       
-       if (this->count <= position)
-       {
-               return INVALID_ARG;
-       }
-
-       iterator = this->public.create_iterator(&(this->public),TRUE);
-       iterator->iterate(iterator, item);
-       for (i = 0; i < position; i++)
-       {
-               if (!iterator->iterate(iterator, item))
+               else
                {
-                       iterator->destroy(iterator);
-                       return INVALID_ARG;
+                       current = current->next;
                }
        }
-       iterator->destroy(iterator);
-       return SUCCESS;
+       return removed;
 }
 
 /**
- * Implementation of linked_list_t.get_last.
+ * Implementation of linked_list_t.remove_at.
  */
-static status_t get_last(private_linked_list_t *this, void **item)
+static void remove_at(private_linked_list_t *this, private_enumerator_t *enumerator)
 {
-       if (this->count == 0)
+       if (enumerator->current)
        {
-               return NOT_FOUND;
+               remove_element(this, enumerator->current);
+               enumerator->current = NULL;
+               enumerator->next = this->first;
        }
-
-       *item = this->last->value;
-
-       return SUCCESS;
 }
 
 /**
@@ -895,9 +829,8 @@ linked_list_t *linked_list_create()
        this->public.insert_last = (void (*) (linked_list_t *, void *item))insert_last;
        this->public.remove_first = (status_t (*) (linked_list_t *, void **item))remove_first;
        this->public.remove_last = (status_t (*) (linked_list_t *, void **item))remove_last;
-       this->public.insert_at_position = (status_t (*) (linked_list_t *,size_t, void *))insert_at_position;
-       this->public.remove_at_position = (status_t (*) (linked_list_t *,size_t, void **))remove_at_position;
-       this->public.get_at_position = (status_t (*) (linked_list_t *,size_t, void **))get_at_position;
+       this->public.remove = (int(*)(linked_list_t*, void *item, bool (*compare)(void *,void*)))remove;
+       this->public.remove_at = (void(*)(linked_list_t*, enumerator_t *enumerator))remove_at;
        this->public.invoke_offset = (void (*)(linked_list_t*,size_t))invoke_offset;
        this->public.invoke_function = (void (*)(linked_list_t*,void(*)(void*)))invoke_function;
        this->public.clone_offset = (linked_list_t * (*)(linked_list_t*,size_t))clone_offset;
index ac36ef46d9c27567b1c3eb058a294fde65b35ffa..3d7133f9da51ba6cfc02e405840b9f56e368ff34 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file linked_list.h
- * 
- * @brief Interface of linked_list_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Tobias Brunner
  * Copyright (C) 2005-2006 Martin Willi
  * WITHOUT ANY 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 linked_list linked_list
+ * @{ @ingroup utils
  */
 
 #ifndef LINKED_LIST_H_
@@ -42,51 +42,42 @@ typedef struct linked_list_t linked_list_t;
  * @return
  *                                             - TRUE, if the item matched
  *                                             - FALSE, otherwise
- * @ingroup utils
  */
 typedef bool (*linked_list_match_t)(void *item, ...);
 
 /**
- * @brief Class implementing a double linked list.
+ * Class implementing a double linked list.
  *
  * General purpose linked list. This list is not synchronized.
- *
- * @b Costructors:
- * - linked_list_create()
- *
- * @ingroup utils
  */
 struct linked_list_t {
 
        /**
-        * @brief Gets the count of items in the list.
+        * Gets the count of items in the list.
         * 
-        * @param this          calling object
         * @return                      number of items in list
         */
        int (*get_count) (linked_list_t *this);
        
        /**
-        * @brief Creates a iterator for the given list.
+        * Creates a iterator for the given list.
         * 
         * @warning Created iterator_t object has to get destroyed by the caller.
         *
         * @deprecated Iterator is obsolete and will disappear, it is too
         * complicated to implement. Use enumerator instead.
         * 
-        * @param this          calling object
         * @param forward       iterator direction (TRUE: front to end)
         * @return                      new iterator_t object
         */
        iterator_t *(*create_iterator) (linked_list_t *this, bool forward);
        
        /**
-        * @brief Creates a iterator, locking a mutex.
+        * Creates a iterator, locking a mutex.
         *
         * The supplied mutex is acquired immediately, and released
         * when the iterator gets destroyed.
         * 
-        * @param this          calling object
         * @param mutex         mutex to use for exclusive access
         * @return                      new iterator_t object
         */
@@ -94,113 +85,86 @@ struct linked_list_t {
                                                                                   pthread_mutex_t *mutex);
        
        /**
-        * @brief Create an enumerator over the list.
+        * Create an enumerator over the list.
         *
         * The enumerator is a "lightweight" iterator. It only has two methods
         * and should therefore be much easier to implement.
         *
-        * @param this          calling object
         * @return                      enumerator over list items
         */
        enumerator_t* (*create_enumerator)(linked_list_t *this);
        
        /**
-        * @brief Inserts a new item at the beginning of the list.
+        * Inserts a new item at the beginning of the list.
         *
-        * @param this          calling object
-        * @param[in] item      item value to insert in list
+        * @param item          item value to insert in list
         */
        void (*insert_first) (linked_list_t *this, void *item);
 
        /**
-        * @brief Removes the first item in the list and returns its value.
+        * Removes the first item in the list and returns its value.
         * 
-        * @param this          calling object
-        * @param[out] item returned value of first item, or NULL
-        * @return
-        *                                      - SUCCESS
-        *                                      - NOT_FOUND, if list is empty
+        * @param item          returned value of first item, or NULL
+        * @return                      SUCCESS, or NOT_FOUND if list is empty
         */
        status_t (*remove_first) (linked_list_t *this, void **item);
-
-       /**
-        * @brief Returns the value of the first list item without removing it.
-        * 
-        * @param this          calling object
-        * @param[out] item     returned value of first item
-        * @return
-        *                                      - SUCCESS
-        *                                      - NOT_FOUND, if list is empty
-        */
-       status_t (*get_first) (linked_list_t *this, void **item);
-
+       
        /**
-        * @brief Inserts a new item at the end of the list.
-        * 
-        * @param this          calling object
-        * @param[in] item      value to insert into list
+        * Remove an item from the list where the enumerator points to.
+        *
+        * @param enumerator enumerator with position
         */
-       void (*insert_last) (linked_list_t *this, void *item);
+       void (*remove_at)(linked_list_t *this, enumerator_t *enumerator);
        
        /**
-        * @brief Inserts a new item at a given position in the list.
+        * Remove items from the list matching item.
         * 
-        * @param this          calling object
-        * @param position      position starting at 0 to insert new entry
-        * @param[in] item      value to insert into list
-        * @return
-        *                                      - SUCCESS
-        *                                      - INVALID_ARG if position not existing
+        * If a compare function is given, it is called for each item, where
+        * the first parameter is the current list item and the second parameter
+        * is the supplied item parameter.
+        * If compare is NULL, compare is is done by pointer.
+        *
+        * @param item          item to remove/pass to comparator
+        * @param compare       compare function, or NULL
+        * @return                      number of removed items
         */
-       status_t (*insert_at_position) (linked_list_t *this,size_t position, void *item);
+       int (*remove)(linked_list_t *this, void *item, bool (*compare)(void *,void*));
        
        /**
-        * @brief Removes an item from a given position in the list.
+        * Returns the value of the first list item without removing it.
         * 
         * @param this          calling object
-        * @param position      position starting at 0 to remove entry from
-        * @param[out] item removed item will be stored at this location
-        * @return
-        *                                              - SUCCESS
-        *                                              - INVALID_ARG if position not existing
+        * @param item          returned value of first item
+        * @return                      SUCCESS, NOT_FOUND if list is empty
         */
-       status_t (*remove_at_position) (linked_list_t *this, size_t position, void **item);
+       status_t (*get_first) (linked_list_t *this, void **item);
 
        /**
-        * @brief Get an item from a given position in the list.
+        * Inserts a new item at the end of the list.
         * 
-        * @param this          calling object
-        * @param position      position starting at 0 to get entry from
-        * @param[out] item     item will be stored at this location
-        * @return
-        *                                              - SUCCESS
-        *                                              - INVALID_ARG if position not existing
+        * @param item          value to insert into list
         */
-       status_t (*get_at_position) (linked_list_t *this, size_t position, void **item);
+       void (*insert_last) (linked_list_t *this, void *item);
 
        /**
-        * @brief Removes the last item in the list and returns its value.
+        * Removes the last item in the list and returns its value.
         * 
         * @param this          calling object
-        * @param[out] item     returned value of last item, or NULL
-        * @return
-        *                                              - SUCCESS
-        *                                              - NOT_FOUND if list is empty
+        * @param item          returned value of last item, or NULL
+        * @return                      SUCCESS, NOT_FOUND if list is empty
         */
        status_t (*remove_last) (linked_list_t *this, void **item);
 
        /**
-        * @brief Returns the value of the last list item without removing it.
+        * Returns the value of the last list item without removing it.
         * 
         * @param this          calling object
-        * @param[out] item     returned value of last item
-        * @return
-        *                                      - SUCCESS
-        *                                      - NOT_FOUND if list is empty
+        * @param item          returned value of last item
+        * @return                      SUCCESS, NOT_FOUND if list is empty
         */
        status_t (*get_last) (linked_list_t *this, void **item);
        
-       /** @brief Find the first matching element in the list.
+       /** Find the first matching element in the list.
         * 
         * The first object passed to the match function is the current list item,
         * followed by the user supplied data.
@@ -210,19 +174,15 @@ struct linked_list_t {
         * 
         * @warning Only use pointers as user supplied data.
         *
-        * @param this                  calling object
         * @param match                 comparison function to call on each object
-        * @param[out] item             
-        *                                              - the list item, if found
-        *                                              - NULL, otherwise
+        * @param item                  the list item, if found
         * @param ...                   user data to supply to match function (limited to 5 arguments)
-        * @return                              
-        *                                              - SUCCESS, if found
-        *                                              - NOT_FOUND, otherwise
+        * @return                              SUCCESS if found, NOT_FOUND otherwise
         */
-       status_t (*find_first) (linked_list_t *this, linked_list_match_t match, void **item, ...);
+       status_t (*find_first) (linked_list_t *this, linked_list_match_t match,
+                                                       void **item, ...);
        
-       /** @brief Find the last matching element in the list.
+       /** Find the last matching element in the list.
         * 
         * The first object passed to the match function is the current list item,
         * followed by the user supplied data.
@@ -232,20 +192,16 @@ struct linked_list_t {
         * 
         * @warning Only use pointers as user supplied data.
         *
-        * @param this                  calling object
         * @param match                 comparison function to call on each object
-        * @param[out] item             
-        *                                              - the list item, if found
-        *                                              - NULL, otherwise
+        * @param item                  the list item, if found
         * @param ...                   user data to supply to match function (limited to 5 arguments)
-        * @return                              
-        *                                              - SUCCESS, if found
-        *                                              - NOT_FOUND, otherwise
+        * @return                              SUCCESS if found, NOT_FOUND otherwise
         */
-       status_t (*find_last) (linked_list_t *this, linked_list_match_t match, void **item, ...);
+       status_t (*find_last) (linked_list_t *this, linked_list_match_t match,
+                                                  void **item, ...);
        
        /**
-        * @brief Invoke a method on all of the contained objects.
+        * Invoke a method on all of the contained objects.
         *
         * If a linked list contains objects with function pointers,
         * invoke() can call a method on each of the objects. The
@@ -253,79 +209,68 @@ struct linked_list_t {
         * which can be evalutated at compile time using the offsetof
         * macro, e.g.: list->invoke(list, offsetof(object_t, method));
         * 
-        * @param this          calling object
         * @param offset        offset of the method to invoke on objects
         */
        void (*invoke_offset) (linked_list_t *this, size_t offset);
        
        /**
-        * @brief Invoke a function on all of the contained objects.
+        * Invoke a function on all of the contained objects.
         * 
-        * @param this          calling object
         * @param offset        offset of the method to invoke on objects
         */
        void (*invoke_function) (linked_list_t *this, void (*)(void*));
        
        /**
-        * @brief Clones a list and its objects using the objects' clone method.
+        * Clones a list and its objects using the objects' clone method.
         * 
-        * @param this          calling object
         * @param offset        offset ot the objects clone function
         * @return                      cloned list
         */
        linked_list_t *(*clone_offset) (linked_list_t *this, size_t offset);
        
        /**
-        * @brief Clones a list and its objects using a given function.
+        * Clones a list and its objects using a given function.
         * 
-        * @param this          calling object
         * @param function      function that clones an object
         * @return                      cloned list
         */
        linked_list_t *(*clone_function) (linked_list_t *this, void*(*)(void*));
        
        /**
-        * @brief Destroys a linked_list object.
-        * 
-        * @param this          calling object
+        * Destroys a linked_list object.
         */
        void (*destroy) (linked_list_t *this);
        
        /**
-        * @brief Destroys a list and its objects using the destructor.
+        * Destroys a list and its objects using the destructor.
         *
         * If a linked list and the contained objects should be destroyed, use
         * destroy_offset. The supplied offset specifies the destructor to
         * call on each object. The offset may be calculated using the offsetof
         * macro, e.g.: list->destroy_offset(list, offsetof(object_t, destroy));
         *
-        * @param this          calling object
         * @param offset        offset of the objects destructor
         */
        void (*destroy_offset) (linked_list_t *this, size_t offset);
        
        /**
-        * @brief Destroys a list and its contents using a a cleanup function.
+        * Destroys a list and its contents using a a cleanup function.
         * 
         * If a linked list and its contents should get destroyed using a specific
         * cleanup function, use destroy_function. This is useful when the
         * list contains malloc()-ed blocks which should get freed,
         * e.g.: list->destroy_function(list, free);
         *
-        * @param this          calling object
         * @param function      function to call on each object
         */
        void (*destroy_function) (linked_list_t *this, void (*)(void*));
 };
 
 /**
- * @brief Creates an empty linked list object.
+ * Creates an empty linked list object.
  * 
  * @return             linked_list_t object.
- * 
- * @ingroup utils
  */
 linked_list_t *linked_list_create(void);
 
-
-#endif /*LINKED_LIST_H_*/
+#endif /*LINKED_LIST_H_ @} */
diff --git a/src/libstrongswan/utils/mutex.c b/src/libstrongswan/utils/mutex.c
new file mode 100644 (file)
index 0000000..f16c5b2
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "mutex.h"
+
+#include <library.h>
+#include <debug.h>
+
+#include <pthread.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+
+typedef struct private_mutex_t private_mutex_t;
+typedef struct private_n_mutex_t private_n_mutex_t;
+typedef struct private_r_mutex_t private_r_mutex_t;
+typedef struct private_condvar_t private_condvar_t;
+
+/**
+ * private data of mutex
+ */
+struct private_mutex_t {
+
+       /**
+        * public functions
+        */
+       mutex_t public;
+       
+       /**
+        * wrapped pthread mutex
+        */
+       pthread_mutex_t mutex;
+};
+
+/**
+ * private data of mutex, extended by recursive locking information
+ */
+struct private_r_mutex_t {
+
+       /**
+        * public functions
+        */
+       private_mutex_t generic;
+       
+       /**
+        * thread which currently owns mutex
+        */
+       pthread_t thread;
+       
+       /**
+        * times we have locked the lock
+        */
+       int times;
+};
+
+/**
+ * private data of condvar
+ */
+struct private_condvar_t {
+
+       /**
+        * public functions
+        */
+       condvar_t public;
+       
+       /**
+        * wrapped pthread condvar
+        */
+       pthread_cond_t condvar;
+};
+
+/**
+ * Implementation of mutex_t.lock.
+ */
+static void lock(private_mutex_t *this)
+{
+       if (pthread_mutex_lock(&this->mutex))
+       {
+               DBG1("!!!! MUTEX %sLOCK ERROR, your code is buggy !!!", "");
+       }
+}
+
+/**
+ * Implementation of mutex_t.unlock.
+ */
+static void unlock(private_mutex_t *this)
+{
+       if (pthread_mutex_unlock(&this->mutex))
+       {
+               DBG1("!!!! MUTEX %sLOCK ERROR, your code is buggy !!!", "UN");
+       }
+}
+
+/**
+ * Implementation of mutex_t.lock.
+ */
+static void lock_r(private_r_mutex_t *this)
+{
+       pthread_t self = pthread_self();
+
+       if (this->thread == self)
+       {
+               this->times++;
+               return;
+       }
+       lock(&this->generic);
+       this->thread = self;
+       this->times = 1;
+}
+
+/**
+ * Implementation of mutex_t.unlock.
+ */
+static void unlock_r(private_r_mutex_t *this)
+{
+       if (--this->times == 0)
+       {
+               this->thread = 0;
+               unlock(&this->generic);
+       }
+}
+
+/**
+ * Implementation of mutex_t.destroy
+ */
+static void mutex_destroy(private_mutex_t *this)
+{
+       pthread_mutex_destroy(&this->mutex);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+mutex_t *mutex_create(mutex_type_t type)
+{
+       switch (type)
+       {
+               case MUTEX_RECURSIVE:
+               {
+                       private_r_mutex_t *this = malloc_thing(private_r_mutex_t);
+       
+                       this->generic.public.lock = (void(*)(mutex_t*))lock_r;
+                       this->generic.public.unlock = (void(*)(mutex_t*))unlock_r;
+                       this->generic.public.destroy = (void(*)(mutex_t*))mutex_destroy;        
+       
+                       pthread_mutex_init(&this->generic.mutex, NULL);
+                       this->thread = 0;
+                       this->times = 0;
+       
+                       return &this->generic.public;
+               }
+               case MUTEX_DEFAULT:
+               default:
+               {
+                       private_mutex_t *this = malloc_thing(private_mutex_t);
+               
+                       this->public.lock = (void(*)(mutex_t*))lock;
+                       this->public.unlock = (void(*)(mutex_t*))unlock;
+                       this->public.destroy = (void(*)(mutex_t*))mutex_destroy;
+               
+                       pthread_mutex_init(&this->mutex, NULL);
+               
+                       return &this->public;
+               }
+       }
+}
+
+/**
+ * Implementation of condvar_t.wait.
+ */
+static void wait(private_condvar_t *this, private_mutex_t *mutex)
+{
+       pthread_cond_wait(&this->condvar, &mutex->mutex);
+}
+
+/**
+ * Implementation of condvar_t.timed_wait.
+ */
+static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
+                                          u_int timeout)
+{
+       struct timespec ts;
+       struct timeval tv;
+       u_int s, ms;
+       
+       gettimeofday(&tv, NULL);
+       
+       s = timeout / 1000;
+       ms = timeout % 1000;
+       
+       ts.tv_sec = tv.tv_sec + s;
+       ts.tv_nsec = tv.tv_usec * 1000 + ms * 1000000;
+       if (ts.tv_nsec > 1000000000 /* 1s */)
+       {
+               ts.tv_nsec -= 1000000000;
+               ts.tv_sec++;
+       }
+       return (pthread_cond_timedwait(&this->condvar, &mutex->mutex,
+                                                                  &ts) == ETIMEDOUT);
+}
+
+/**
+ * Implementation of condvar_t.signal.
+ */
+static void signal(private_condvar_t *this)
+{
+       pthread_cond_signal(&this->condvar);
+}
+
+/**
+ * Implementation of condvar_t.broadcast.
+ */
+static void broadcast(private_condvar_t *this)
+{
+       pthread_cond_broadcast(&this->condvar);
+}
+
+/**
+ * Implementation of condvar_t.destroy
+ */
+static void condvar_destroy(private_condvar_t *this)
+{
+       pthread_cond_destroy(&this->condvar);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+condvar_t *condvar_create(condvar_type_t type)
+{
+       switch (type)
+       {
+               case CONDVAR_DEFAULT:
+               default:
+               {
+                       private_condvar_t *this = malloc_thing(private_condvar_t);
+               
+                       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.signal = (void(*)(condvar_t*))signal;
+                       this->public.broadcast = (void(*)(condvar_t*))broadcast;
+                       this->public.destroy = (void(*)(condvar_t*))condvar_destroy;
+               
+                       pthread_cond_init(&this->condvar, NULL);
+               
+                       return &this->public;
+               }
+       }
+}
+
diff --git a/src/libstrongswan/utils/mutex.h b/src/libstrongswan/utils/mutex.h
new file mode 100644 (file)
index 0000000..cf557c3
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup mutex mutex
+ * @{ @ingroup utils
+ */
+
+#ifndef MUTEX_H_
+#define MUTEX_H_
+
+typedef struct mutex_t mutex_t;
+typedef struct condvar_t condvar_t;
+typedef enum mutex_type_t mutex_type_t;
+typedef enum condvar_type_t condvar_type_t;
+
+#include <library.h>
+
+/**
+ * Type of mutex.
+ */
+enum mutex_type_t {
+       /** default mutex */
+       MUTEX_DEFAULT   = 0,
+       /** allow recursive locking of the mutex */
+       MUTEX_RECURSIVE = 1,
+};
+
+/**
+ * Type of condvar.
+ */
+enum condvar_type_t {
+       /** default condvar */
+       CONDVAR_DEFAULT = 0,
+};
+
+/**
+ * Mutex wrapper implements simple, portable and advanced mutex functions.
+ */
+struct mutex_t {
+
+       /**
+        * Acquire the lock to the mutex.
+        */
+       void (*lock)(mutex_t *this);
+       
+       /**
+        * Release the lock on the mutex.
+        */
+       void (*unlock)(mutex_t *this);
+                       
+       /**
+     * Destroy a mutex instance.
+     */
+    void (*destroy)(mutex_t *this);
+};
+
+/**
+ * Condvar wrapper to use in conjunction with mutex_t.
+ */
+struct condvar_t {
+
+       /**
+        * Wait on a condvar until it gets signalized.
+        *
+        * @param mutex                 mutex to release while waiting
+        */
+       void (*wait)(condvar_t *this, mutex_t *mutex);
+       
+       /**
+        * Wait on a condvar until it gets signalized, or times out.
+        *
+        * @param mutex                 mutex to release while waiting
+        * @param timeout               timeout im ms
+        * @return                              TRUE if timed out, FALSE otherwise
+        */
+       bool (*timed_wait)(condvar_t *this, mutex_t *mutex, u_int timeout);
+       
+       /**
+        * Wake up a single thread in a condvar.
+        */
+       void (*signal)(condvar_t *this);
+       
+       /**
+        * Wake up all threads in a condvar.
+        */
+       void (*broadcast)(condvar_t *this);
+       
+       /**
+        * Destroy a condvar and free its resources.
+        */
+       void (*destroy)(condvar_t *this);
+};
+
+/**
+ * Create a mutex instance.
+ *
+ * @param type         type of mutex to create
+ * @return                     unlocked mutex instance
+ */
+mutex_t *mutex_create(mutex_type_t type);
+
+/**
+ * Create a condvar instance.
+ *
+ * @param type         type of condvar to create
+ * @return                     condvar instance
+ */
+condvar_t *condvar_create(condvar_type_t type);
+
+#endif /* MUTEX_H_ @}*/
index 39e38cc58e163985dc744ad80321f41baaf466c1..38302105daefc77884ca8bf8071d323e3d228f38 100644 (file)
@@ -1,13 +1,5 @@
-/**
- * @file optionsfrom.c
- * 
- * @brief read command line options from a file
- * 
- */
-
 /*
  * Copyright (C) 2007-2008 Andreas Steffen
- *
  * Hochschule fuer Technik Rapperswil
  *
  * This library is free software; you can redistribute it and/or modify it
@@ -20,7 +12,7 @@
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
  * License for more details.
  *
- * RCSID $Id$
+ * $Id$
  */
 
 #include <stdio.h>
index 0014cec368de77d8532a5d4e9bfcb6e21b8735a8..3a5640907fd60c876cb8d64668ad0b1c272d85b2 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file optionsfrom.h
- * 
- * @brief Read command line options from a file
- * 
- */
-
 /*
  * Copyright (C) 2007-2008 Andreas Steffen
  *
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  *
- * RCSID $Id$
+ * $Id$
+ */
+/**
+ * @defgroup optionsfrom optionsfrom
+ * @{ @ingroup utils
  */
 
 #ifndef OPTIONSFROM_H_
 typedef struct options_t options_t;
 
 /**
- * @brief options object.
- * 
- * @b Constructors:
- *  - options_create()
- *
- * @ingroup utils
+ * Reads additional command line arguments from a file
  */
 struct options_t {
+       
        /**
-        * @brief Check if the PKCS#7 contentType is data
+        * Check if the PKCS#7 contentType is data
         *
-        * @param this                  calling object
         * @param filename              file containing the options
         * @param argcp                 pointer to argc
         * @param argvp                 pointer to argv[]
         * @param optind                current optind, number of next argument
         * @return                              TRUE if optionsfrom parsing successful
         */
-       bool (*from) (options_t * this, char *filename, int *argcp, char **argvp[], int optind);
+       bool (*from) (options_t * this, char *filename,
+                                 int *argcp, char **argvp[], int optind);
 
        /**
-        * @brief Destroys the options_t object.
-        *
-        * @param this                  options_t object to destroy
+        * Destroys the options_t object.
         */
        void (*destroy) (options_t *this);
 };
 
 /**
- * @brief Create an options object.
+ * Create an options object.
  *
  * @return                                     created options_t object
- *
- * @ingroup utils
  */
 options_t *options_create(void);
 
-#endif /*OPTIONSFROM_H_*/
+#endif /*OPTIONSFROM_H_ @} */
index c15d108c76c50b4e0454563d933029f76b29da80..74db0dead29304045b6293228f492886654c4fb8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file randomizer.c
- * 
- * @brief Implementation of randomizer_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
  * WITHOUT ANY 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>
@@ -41,25 +36,13 @@ struct private_randomizer_t {
         * Public randomizer_t interface.
         */
        randomizer_t public;
-       
-       /**
-        * @brief Reads a specific number of bytes from random or pseudo random device.
-        * 
-        * @param this                                  calling object
-        * @param pseudo_random                 TRUE, if from pseudo random bytes should be read,
-        *                                                              FALSE for true random bytes
-        * @param bytes                                 number of bytes to read
-        * @param[out] buffer                   pointer to buffer where to write the data in.
-        *                                                              Size of buffer has to be at least bytes.
-        */
-       status_t (*get_bytes_from_device) (private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer);
 };
 
-
 /**
- * Implementation of private_randomizer_t.get_bytes_from_device.
+ * Read bytes from the random device
  */
-static status_t get_bytes_from_device(private_randomizer_t *this,bool pseudo_random, size_t bytes, u_int8_t *buffer)
+static status_t read_bytes(private_randomizer_t *this,
+                                                  bool pseudo_random, size_t bytes, u_int8_t *buffer)
 {
        size_t ndone;
        int device;
@@ -91,20 +74,22 @@ static status_t get_bytes_from_device(private_randomizer_t *this,bool pseudo_ran
 /**
  * Implementation of randomizer_t.get_random_bytes.
  */
-static status_t get_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer)
+static status_t get_random_bytes(private_randomizer_t *this,size_t bytes,
+                                                                u_int8_t *buffer)
 {
-       return this->get_bytes_from_device(this, FALSE, bytes, buffer);
+       return read_bytes(this, FALSE, bytes, buffer);
 }
 
 /**
  * Implementation of randomizer_t.allocate_random_bytes.
  */
-static status_t allocate_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk)
+static status_t allocate_random_bytes(private_randomizer_t *this, size_t bytes,
+                                                                         chunk_t *chunk)
 {
        status_t status;
        chunk->len = bytes;
        chunk->ptr = malloc(bytes);
-       status = this->get_bytes_from_device(this, FALSE, bytes, chunk->ptr);
+       status = read_bytes(this, FALSE, bytes, chunk->ptr);
        if (status != SUCCESS)
        {
                free(chunk->ptr);
@@ -115,20 +100,22 @@ static status_t allocate_random_bytes(private_randomizer_t *this, size_t bytes,
 /**
  * Implementation of randomizer_t.get_pseudo_random_bytes.
  */
-static status_t get_pseudo_random_bytes(private_randomizer_t *this,size_t bytes, u_int8_t *buffer)
+static status_t get_pseudo_random_bytes(private_randomizer_t *this, 
+                                                                               size_t bytes, u_int8_t *buffer)
 {
-       return (this->get_bytes_from_device(this, TRUE, bytes, buffer));
+       return read_bytes(this, TRUE, bytes, buffer);
 }
 
 /**
  * Implementation of randomizer_t.allocate_pseudo_random_bytes.
  */
-static status_t allocate_pseudo_random_bytes(private_randomizer_t *this, size_t bytes, chunk_t *chunk)
+static status_t allocate_pseudo_random_bytes(private_randomizer_t *this,
+                                                                                        size_t bytes, chunk_t *chunk)
 {
        status_t status;
        chunk->len = bytes;
        chunk->ptr = malloc(bytes);
-       status = this->get_bytes_from_device(this, TRUE, bytes, chunk->ptr);
+       status = read_bytes(this, TRUE, bytes, chunk->ptr);
        if (status != SUCCESS)
        {
                free(chunk->ptr);
@@ -158,8 +145,6 @@ randomizer_t *randomizer_create(void)
        this->public.allocate_pseudo_random_bytes = (status_t (*) (randomizer_t *,size_t, chunk_t *)) allocate_pseudo_random_bytes;
        this->public.destroy = (void (*) (randomizer_t *))destroy;
        
-       /* private functions */
-       this->get_bytes_from_device = get_bytes_from_device;
-       
-       return &(this->public);
+       return &this->public;
 }
+
index afbade059a4dcec2c8ce939cb1d37c8b0298965b..c7aa86b01209c538a8666ca8c1a6b6a3163470bc 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file randomizer.h
- * 
- * @brief Interface of randomizer_t.
- * 
- */
-
 /*
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * WITHOUT ANY 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 randomizer randomizer
+ * @{ @ingroup utils
  */
 
 #ifndef RANDOMIZER_H_
@@ -43,72 +43,59 @@ typedef struct randomizer_t randomizer_t;
 #endif
 
 /**
- * @brief Class used to get random and pseudo random values.
- * 
- * @b Constructors:
- *  - randomizer_create()
- * 
- * @ingroup utils
+ * Class used to get random and pseudo random values.
  */
 struct randomizer_t {
        
        /**
-        * @brief Reads a specific number of bytes from random device.
-        * 
-        * @param this                                  calling randomizer_t object
-        * @param bytes                                 number of bytes to read
-        * @param[out] buffer                   pointer to buffer where to write the data in.
-        *                                                              Size of buffer has to be at least bytes.
-        * @return                                              SUCCESS, or FAILED
+        * Reads a specific number of bytes from random device.
+        *
+        * @param bytes                 number of bytes to read
+        * @param buffer                pointer to buffer where to write the data in.
+        * @return                              SUCCESS, or FAILED
         */
-       status_t (*get_random_bytes) (randomizer_t *this, size_t bytes, u_int8_t *buffer);
+       status_t (*get_random_bytes) (randomizer_t *this,
+                                                                 size_t bytes, u_int8_t *buffer);
        
        /**
-        * @brief Allocates space and writes in random bytes.
+        * Allocates space and writes in random bytes.
         * 
-        * @param this                                  calling randomizer_t object
-        * @param bytes                                 number of bytes to allocate
-        * @param[out] chunk                    chunk which will hold the allocated random bytes
-        * @return                                              SUCCESS, or FAILED
+        * @param bytes                 number of bytes to allocate
+        * @param chunk                 chunk which will hold the allocated random bytes
+        * @return                              SUCCESS, or FAILED
         */     
-       status_t (*allocate_random_bytes) (randomizer_t *this, size_t bytes, chunk_t *chunk);
+       status_t (*allocate_random_bytes) (randomizer_t *this,
+                                                                          size_t bytes, chunk_t *chunk);
        
        /**
-        * @brief Reads a specific number of bytes from pseudo random device.
+        * Reads a specific number of bytes from pseudo random device.
         * 
-        * @param this                                  calling randomizer_t object
-        * @param bytes                                 number of bytes to read
-        * @param[out] buffer                   pointer to buffer where to write the data in.
-        *                                                              size of buffer has to be at least bytes.
-        * @return                                              SUCCESS, or FAILED
+        * @param bytes                 number of bytes to read
+        * @param buffer                pointer to buffer where to write the data in.
+        * @return                              SUCCESS, or FAILED
         */
        status_t (*get_pseudo_random_bytes) (randomizer_t *this,size_t bytes, u_int8_t *buffer);
        
        /**
-        * @brief Allocates space and writes in pseudo random bytes.
+        * Allocates space and writes in pseudo random bytes.
         * 
-        * @param this                                  calling randomizer_t object
-        * @param bytes                                 number of bytes to allocate
-        * @param[out] chunk                    chunk which will hold the allocated random bytes
-        * @return                                              SUCCESS, or FAILED
+        * @param bytes                 number of bytes to allocate
+        * @param chunk                 chunk which will hold the allocated random bytes
+        * @return                              SUCCESS, or FAILED
         */     
        status_t (*allocate_pseudo_random_bytes) (randomizer_t *this, size_t bytes, chunk_t *chunk);
 
        /**
-        * @brief Destroys a randomizer_t object.
-        *
-        * @param this  randomizer_t object to destroy
+        * Destroys a randomizer_t object.
         */
        void (*destroy) (randomizer_t *this);
 };
 
 /**
- * @brief Creates a randomizer_t object.
- * 
- * @return     created randomizer_t, or
+ * Creates a randomizer_t object.
  * 
- * @ingroup utils
+ * @return     created randomizer_t
  */
 randomizer_t *randomizer_create(void);
 
-#endif /*RANDOMIZER_H_*/
+#endif /*RANDOMIZER_H_ @} */
index 7f77d1dba7516faa8657dc61c2a95e039888697e..366022fd11fdbb79f313c9c6d23b2ced03296a44 100644 (file)
@@ -1,27 +1,16 @@
 ipsec_PROGRAMS = manager.fcgi
 
 manager_fcgi_SOURCES = \
-main.c manager.c manager.h gateway.h gateway.c database.h database.c \
+main.c manager.c manager.h gateway.h gateway.c storage.h storage.c xml.h xml.c \
 controller/auth_controller.c controller/auth_controller.h \
 controller/ikesa_controller.c controller/ikesa_controller.h \
 controller/control_controller.c controller/control_controller.h \
 controller/config_controller.c controller/config_controller.h \
 controller/gateway_controller.c controller/gateway_controller.h
 
-manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
+manager_fcgi_LDADD = $(top_builddir)/src/libfast/libfast.la ${xml_LIBS}
 
-
-
-lib_LTLIBRARIES = libappserv.la
-
-libappserv_la_SOURCES = \
-lib/context.h lib/dispatcher.c lib/request.h lib/session.h \
-lib/controller.h lib/dispatcher.h lib/request.c lib/session.c \
-lib/xml.h lib/xml.c 
-
-libappserv_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl ${xml_LIBS}
-
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/manager/lib -I/usr/include/ClearSilver ${xml_CFLAGS}
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libfast ${xml_CFLAGS}
 AM_CFLAGS = -rdynamic -DIPSECDIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\"
 
 ipsec_DATA = manager.db
index e9b86941ad3b3b3685dfe58412b73a8ee9c2e428..cccee8888361c4e177e0e83574fb4155c5d8255b 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file auth_controller.c
- *
- * @brief Implementation of auth_controller_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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_controller.h"
index c90546a179ae13e45d9dc096e93312da8d92f948..2e9f93459f587fc03d281bbfe0893fb70399d4f3 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file auth_controller.h
- * 
- * @brief Interface of auth_controller_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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_controller auth_controller
+ * @{ @ingroup controller
  */
 
 #ifndef AUTH_CONTROLLER_H_
@@ -29,7 +29,7 @@
 typedef struct auth_controller_t auth_controller_t;
 
 /**
- * @brief Authentication controller.
+ * Authentication controller.
  */
 struct auth_controller_t {
 
@@ -40,8 +40,8 @@ struct auth_controller_t {
 };
 
 /**
- * @brief Create a auth_controller controller instance.
+ * Create a auth_controller controller instance.
  */
 controller_t *auth_controller_create(context_t *context, void *param);
 
-#endif /* AUTH_CONTROLLER_H_ */
+#endif /* AUTH_CONTROLLER_H_ @} */
index e7941ada45178b970fc008ff3ad6d3e2fce40e55..34f054a7313d75c04c469733b9cebdbc59f43ccb 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file config_controller.c
- *
- * @brief Implementation of config_controller_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "config_controller.h"
index fcf5f5c49837c866083c0cff65c1a28e80eb74d7..edc5cd0d01c7862d19e0c904c55fbc5957c741e6 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file config_controller.h
- * 
- * @brief Interface of config_controller_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 config_controller config_controller
+ * @{ @ingroup controller
  */
 
 #ifndef CONFIG_CONTROLLER_H_
@@ -29,7 +29,7 @@
 typedef struct config_controller_t config_controller_t;
 
 /**
- * @brief Status controller.
+ * Status controller.
  */
 struct config_controller_t {
 
@@ -40,8 +40,8 @@ struct config_controller_t {
 };
 
 /**
- * @brief Create a config_controller controller instance.
+ * Create a config_controller controller instance.
  */
 controller_t *config_controller_create(context_t *context, void *param);
 
-#endif /* CONFIG_CONTROLLER_H_ */
+#endif /* CONFIG_CONTROLLER_H_ @} */
index 12cb5e9072679858f6fa1e3de1003d0dd9d93fc3..d49941e2ff5940b1ed798689b84ef0ac18f31e14 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file control_controller.c
- *
- * @brief Implementation of control_controller_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "control_controller.h"
index 6a55170aa1e89959b03c6b36339537506c26afb0..a33cae50efa05b1e84aebdd01beccbdddfb9507c 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file control_controller.h
- * 
- * @brief Interface of control_controller_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 control_controller control_controller
+ * @{ @ingroup controller
  */
 
 #ifndef CONTROL_CONTROLLER_H_
@@ -29,7 +29,7 @@
 typedef struct control_controller_t control_controller_t;
 
 /**
- * @brief Status controller.
+ * Control controller.
  */
 struct control_controller_t {
 
@@ -40,7 +40,7 @@ struct control_controller_t {
 };
 
 /**
- * @brief Create a control_controller controller instance.
+ * Create a control_controller controller instance.
  */
 controller_t *control_controller_create(context_t *context, void *param);
 
index dff1cf3cfeb2b8e4fd784ee38e0cad765a1b234c..e4015e06c8edf8a6df3f5e997417003f07a8ffad 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file gateway_controller.c
- *
- * @brief Implementation of gateway_controller_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "gateway_controller.h"
index 5872e20e2d198c97aefc5204ee0e92d96f148268..eec089d7ebb1c7782840493e13cc9ae89b6c543e 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file gateway_controller.h
- * 
- * @brief Interface of gateway_controller_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 gateway_controller gateway_controller
+ * @{ @ingroup controller
  */
 
 #ifndef GATEWAY_CONTROLLER_H_
@@ -29,7 +29,7 @@
 typedef struct gateway_controller_t gateway_controller_t;
 
 /**
- * @brief Status controller.
+ * Status controller.
  */
 struct gateway_controller_t {
 
@@ -40,8 +40,8 @@ struct gateway_controller_t {
 };
 
 /**
- * @brief Create a gateway_controller controller instance.
+ * Create a gateway_controller controller instance.
  */
 controller_t *gateway_controller_create(context_t *context, void *param);
 
-#endif /* GATEWAY_CONTROLLER_H_ */
+#endif /* GATEWAY_CONTROLLER_H_ @} */
index 2b282b79c474cb1d4a60569bd58454adcd2ec0c7..a52adc189029d90891633cbf9481dd75435b04d8 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ikesa_controller.c
- *
- * @brief Implementation of ikesa_controller_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "ikesa_controller.h"
index 753cccad160b03503d1c7a4eeeda11bbc1e236d5..a238db307d08ee57a3751d992ac7d2ddfe5dd243 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file ikesa_controller.h
- * 
- * @brief Interface of ikesa_controller_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 ikesa_controller ikesa_controller
+ * @{ @ingroup controller
  */
 
 #ifndef IKESA_CONTROLLER_H_
@@ -29,7 +29,7 @@
 typedef struct ikesa_controller_t ikesa_controller_t;
 
 /**
- * @brief Status controller.
+ * Status controller.
  */
 struct ikesa_controller_t {
 
@@ -40,8 +40,8 @@ struct ikesa_controller_t {
 };
 
 /**
- * @brief Create a ikesa_controller controller instance.
+ * Create a ikesa_controller controller instance.
  */
 controller_t *ikesa_controller_create(context_t *context, void *param);
 
-#endif /* IKESA_CONTROLLER_H_ */
+#endif /* IKESA_CONTROLLER_H_ @} */
diff --git a/src/manager/database.c b/src/manager/database.c
deleted file mode 100644 (file)
index a7776c8..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
- * @file database.c
- *
- * @brief Implementation of database_t.
- *
- */
-
-/*
- * 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 "database.h"
-
-#include <sqlite3.h>
-#include <library.h>
-#include <crypto/hashers/hasher.h>
-
-
-typedef struct private_database_t private_database_t;
-
-/**
- * private data of database
- */
-struct private_database_t {
-
-       /**
-        * public functions
-        */
-       database_t public;
-       
-       /**
-        * SQLite database handle
-        */
-       sqlite3 *db;
-};
-
-/**
- * database enumerator implements enumerator_t
- */
-typedef struct  {
-       enumerator_t enumerator;
-       sqlite3_stmt *stmt;
-} db_enumerator_t;
-
-/**
- * destroy a database enumerator
- */
-static void db_enumerator_destroy(db_enumerator_t* this)
-{
-       sqlite3_finalize(this->stmt);
-       free(this);
-}
-
-/**
- * create a database enumerator
- */
-static enumerator_t *db_enumerator_create(bool(*enumerate)(db_enumerator_t*,void*,...),
-                                                                                        sqlite3_stmt *stmt)
-{
-       db_enumerator_t *this = malloc_thing(db_enumerator_t);
-       this->enumerator.enumerate = (void*)enumerate;
-       this->enumerator.destroy = (void*)db_enumerator_destroy;
-       this->stmt = stmt;
-       return &this->enumerator;
-}
-
-/**
- * Implementation of database_t.login.
- */
-static int login(private_database_t *this, char *username, char *password)
-{
-       sqlite3_stmt *stmt;
-       hasher_t *hasher;
-       chunk_t hash, data;
-       size_t username_len, password_len;
-       int uid = 0;
-       char *str;
-       
-       /* hash = SHA1( username | password ) */
-       hasher = hasher_create(HASH_SHA1);
-       hash = chunk_alloca(hasher->get_hash_size(hasher));
-       username_len = strlen(username);
-       password_len = strlen(password);
-       data = chunk_alloca(username_len + password_len);
-       memcpy(data.ptr, username, username_len);
-       memcpy(data.ptr + username_len, password, password_len);
-       hasher->get_hash(hasher, data, hash.ptr);
-       hasher->destroy(hasher);
-       str = chunk_to_hex(hash, FALSE);
-       
-       if (sqlite3_prepare_v2(this->db,
-                       "SELECT oid FROM users WHERE username = ? AND password = ?;",
-                       -1, &stmt, NULL) == SQLITE_OK)
-       {
-               if (sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC) == SQLITE_OK &&
-                       sqlite3_bind_text(stmt, 2, str, -1, SQLITE_STATIC) == SQLITE_OK &&
-                       sqlite3_step(stmt) == SQLITE_ROW)
-               {
-                       uid = sqlite3_column_int(stmt, 0);
-               }
-               sqlite3_finalize(stmt);
-       }
-       free(str);
-       return uid;
-}
-
-/**
- * enumerate function for gateway enumrator
- */
-static bool gateway_enumerate(db_enumerator_t* e, int *id, const char **name,
-                                                         int *port, const char **address)
-{
-       if (sqlite3_step(e->stmt) == SQLITE_ROW)
-       {
-               *id = sqlite3_column_int(e->stmt, 0);
-               *name = sqlite3_column_text(e->stmt, 1);
-               *port = sqlite3_column_int(e->stmt, 2);
-               *address = sqlite3_column_text(e->stmt, 3);
-               return TRUE;
-       }
-       return FALSE;
-}
-
-/**
- * Implementation of database_t.create_gateway_enumerator.
- */
-static enumerator_t* create_gateway_enumerator(private_database_t *this, int user)
-{
-       sqlite3_stmt *stmt;
-       
-       if (sqlite3_prepare_v2(this->db,
-                       "SELECT gateways.oid AS gid, name, port, address FROM "
-                       "gateways, user_gateway AS ug ON gid = ug.gateway WHERE ug.user = ?;",
-                       -1, &stmt, NULL) == SQLITE_OK)
-       {
-               if (sqlite3_bind_int(stmt, 1, user) == SQLITE_OK)
-               {
-                       return db_enumerator_create((void*)gateway_enumerate, stmt);
-               }
-               sqlite3_finalize(stmt);
-       }
-       return enumerator_create_empty();
-}
-
-/**
- * Implementation of database_t.destroy
- */
-static void destroy(private_database_t *this)
-{
-       sqlite3_close(this->db);
-       free(this);
-}
-
-/*
- * see header file
- */
-database_t *database_create(char *dbfile)
-{
-       private_database_t *this = malloc_thing(private_database_t);
-       
-       this->public.login = (int(*)(database_t*, char *username, char *password))login;
-       this->public.create_gateway_enumerator = (enumerator_t*(*)(database_t*,int))create_gateway_enumerator;
-       this->public.destroy = (void(*)(database_t*))destroy;
-       
-       if (sqlite3_open(dbfile, &this->db) != SQLITE_OK)
-       {
-               destroy(this);
-               return NULL;
-       }
-       return &this->public;
-}
-
index d4eb5279ee93a62d45d3272ef433d5fc7f1dc6df..6d5f6f7d2a23b9da41ec7654cf9a8b0c142187eb 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file gateway.c
- *
- * @brief Implementation of gateway_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "gateway.h"
@@ -29,7 +24,7 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
-#include <lib/xml.h>
+#include <xml.h>
 
 typedef struct private_gateway_t private_gateway_t;
 
index 81d8b9c3f70a43c80db8975c0463c64a6381707a..8c012d303e65c6dea50d718cc7c12523c530c2c0 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file gateway.h
- * 
- * @brief Interface of gateway_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 gateway gateway
+ * @{ @ingroup manager
  */
 
 #ifndef GATEWAY_H_
 typedef struct gateway_t gateway_t;
 
 /**
- * @brief A connection to a gateway.
+ * A connection to a gateway.
  */
 struct gateway_t {
        
        /**
-        * @brief Send an XML request to the gateway.
+        * Send an XML request to the gateway.
         *
         * @param xml           xml request string
         * @return                      allocated xml response string
@@ -42,21 +42,21 @@ struct gateway_t {
        char* (*request)(gateway_t *this, char *xml);
        
        /**
-        * @brief Query the list of IKE_SAs and all its children.
+        * Query the list of IKE_SAs and all its children.
         *
         * @return                      enumerator over ikesa XML elements
         */
        enumerator_t* (*query_ikesalist)(gateway_t *this);
        
        /**
-        * @brief Query the list of peer configs and its subconfigs.
+        * Query the list of peer configs and its subconfigs.
         *
         * @return                      enumerator over peerconfig XML elements
         */
        enumerator_t* (*query_configlist)(gateway_t *this);
        
        /**
-        * @brief Terminate an IKE or a CHILD SA.
+        * Terminate an IKE or a CHILD SA.
         *
         * @param ike           TRUE for IKE-, FALSE for a CHILD-SA
         * @param id            ID of the SA to terminate
@@ -65,7 +65,7 @@ struct gateway_t {
        enumerator_t* (*terminate)(gateway_t *this, bool ike, u_int32_t id);
        
        /**
-        * @brief Initiate an IKE or a CHILD SA.
+        * Initiate an IKE or a CHILD SA.
         *
         * @param ike           TRUE for IKE-, FALSE for CHILD-SA
         * @param name          name of the peer/child config
@@ -74,13 +74,13 @@ struct gateway_t {
        enumerator_t* (*initiate)(gateway_t *this, bool ike, char *name);
        
        /**
-     * @brief Destroy a gateway instance.
+     * Destroy a gateway instance.
      */
     void (*destroy)(gateway_t *this);
 };
 
 /**
- * @brief Create a gateway instance using a TCP connection.
+ * Create a gateway instance using a TCP connection.
  *
  * @param name                 name of the gateway
  * @param host                 gateway connection endpoint
@@ -89,11 +89,11 @@ struct gateway_t {
 gateway_t *gateway_create_tcp(char *name, host_t *host);
 
 /**
- * @brief Create a gateway instance using a UNIX socket.
+ * Create a gateway instance using a UNIX socket.
  *
  * @param name                 name of the gateway
  * @param 
  */
 gateway_t *gateway_create_unix(char *name);
 
-#endif /* GATEWAY_H_ */
+#endif /* GATEWAY_H_ @} */
diff --git a/src/manager/lib/dispatcher.h b/src/manager/lib/dispatcher.h
deleted file mode 100644 (file)
index 2748378..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file dispatcher.h
- * 
- * @brief Interface of dispatcher_t.
- * 
- */
-
-/*
- * 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.
- */
-
-#ifndef DISPATCHER_H_
-#define DISPATCHER_H_
-
-#include "controller.h"
-
-typedef struct dispatcher_t dispatcher_t;
-
-/**
- * @brief Dispatcher, accepts connections using multiple threads.
- *
- * The dispatcher creates a session for each client (using SID cookies). In
- * each session, a session context is created using the context constructor.
- * Each controller is instanciated in the session using the controller
- * constructor added with add_controller.
- */
-struct dispatcher_t {
-       
-       /**
-        * @brief Register a controller to the dispatcher.
-        *
-        * The first controller added serves as default controller. Client's
-        * get redirected to it if no other controller matches.
-        *
-        * @param constructor   constructor function to the conntroller
-        * @param param                 param to pass to constructor
-        */
-       void (*add_controller)(dispatcher_t *this,
-                                                  controller_constructor_t constructor, void *param);
-       
-       /**
-        * @brief Start with dispatching.
-        *
-        * It may be necessary to call per-thread initialization functions. 
-        * If init is not NULL, the handler is called right after thread
-        * creation (by the created thread) and the deinit function is called
-        * before the thread gets destroyed (again by the thread itself).
-        *
-        * @param thread                number of dispatching threads
-        * @param init                  thread specific initialization function, or NULL
-        * @param init_param    param to pass to init function
-        * @param deinit                thread dpecific deinitialization function, or NULL
-        * @param deinit_param  param to pass to deinit function
-        */
-       void (*run)(dispatcher_t *this, int threads,
-                               void(*init)(void *param), void *init_param,
-                               void(*deinit)(void *param), void *deinit_param);
-       
-       /**
-        * @brief Wait for a relevant signal action.
-        */
-       void (*waitsignal)(dispatcher_t *this);
-       
-       /**
-        * @brief Destroy the dispatcher_t.
-        */
-       void (*destroy) (dispatcher_t *this);
-};
-
-/**
- * @brief Create a dispatcher.
- *
- * The context constructor is invoked to create a session context for
- * each session.
- *
- * @param socket               FastCGI socket path, NULL for dynamic
- * @param timeout              session timeout
- * @param constructor  construction function for session context
- * @param param                        parameter to supply to context constructor
- */
-dispatcher_t *dispatcher_create(char *socket, int timeout,
-                                                               context_constructor_t constructor, void *param);
-
-#endif /* DISPATCHER_H_ */
index eb4654cede1b960d18da56dce77b27e4324602a5..fc1f5fc2d50ff819d088fb782037ff73999b2a5f 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file main.c
- *
- * @brief Implementation of dispatcher_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 <dispatcher.h>
 #include <stdio.h>
 
 #include "manager.h"
-#include "database.h"
+#include "storage.h"
 #include "controller/auth_controller.h"
 #include "controller/ikesa_controller.h"
 #include "controller/gateway_controller.h"
 int main (int arc, char *argv[])
 {
        dispatcher_t *dispatcher;
-       database_t *database;
+       storage_t *storage;
        char *socket = NULL;
+       bool debug = FALSE;
        
 #ifdef FCGI_SOCKET
        socket = FCGI_SOCKET;
+       debug = TRUE;
 #endif /* FCGI_SOCKET */
+
+       library_init(IPSECDIR "/manager.conf");
        
-       database = database_create(DBFILE);
-       if (database == NULL)
+       storage = storage_create("sqlite://"DBFILE);
+       if (storage == NULL)
        {
                fprintf(stderr, "opening database '%s' failed.\n", DBFILE);
                return 1;
        }
        
-       dispatcher = dispatcher_create(socket, SESSION_TIMEOUT,
-                                               (context_constructor_t)manager_create, database);
+       dispatcher = dispatcher_create(socket, debug, SESSION_TIMEOUT,
+                                               (context_constructor_t)manager_create, storage);
        dispatcher->add_controller(dispatcher, ikesa_controller_create, NULL);
        dispatcher->add_controller(dispatcher, gateway_controller_create, NULL);
        dispatcher->add_controller(dispatcher, auth_controller_create, NULL);
        dispatcher->add_controller(dispatcher, control_controller_create, NULL);
        dispatcher->add_controller(dispatcher, config_controller_create, NULL);
        
-       dispatcher->run(dispatcher, THREADS, NULL, NULL, NULL, NULL);
+       dispatcher->run(dispatcher, THREADS);
        
        dispatcher->waitsignal(dispatcher);
        
        dispatcher->destroy(dispatcher);
-       database->destroy(database);
+       storage->destroy(storage);
+       
+       library_deinit();
 
     return 0;
 }
index 39c8d995a3a79b0882ce34fc6dbe5934a561b3db..2bf2869b59454e3c1479e2f3dfc287761b5884c4 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file manager.c
- *
- * @brief Implementation of manager_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "manager.h"
@@ -39,9 +34,9 @@ struct private_manager_t {
        manager_t public;
        
        /**
-        * underlying database
+        * underlying storage database
         */
-       database_t *db;
+       storage_t *store;
        
        /**
         * user id, if we are logged in
@@ -59,7 +54,7 @@ struct private_manager_t {
  */
 static enumerator_t* create_gateway_enumerator(private_manager_t *this)
 {
-       return this->db->create_gateway_enumerator(this->db, this->user);
+       return this->store->create_gateway_enumerator(this->store, this->user);
 }
 
 /**
@@ -77,7 +72,7 @@ static gateway_t* select_gateway(private_manager_t *this, int select_id)
                if (this->gateway) this->gateway->destroy(this->gateway);
                this->gateway = NULL;
                
-               enumerator = this->db->create_gateway_enumerator(this->db, this->user);
+               enumerator = this->store->create_gateway_enumerator(this->store, this->user);
                while (enumerator->enumerate(enumerator, &id, &name, &port, &address))
                {
                        if (select_id == id)
@@ -117,7 +112,7 @@ static bool login(private_manager_t *this, char *username, char *password)
 {
        if (!this->user)
        {
-               this->user = this->db->login(this->db, username, password);
+               this->user = this->store->login(this->store, username, password);
        }
        return this->user != 0;
 }
@@ -147,7 +142,7 @@ static void destroy(private_manager_t *this)
 /*
  * see header file
  */
-manager_t *manager_create(database_t *database)
+manager_t *manager_create(storage_t *storage)
 {
        private_manager_t *this = malloc_thing(private_manager_t);
        
@@ -159,7 +154,7 @@ manager_t *manager_create(database_t *database)
        this->public.context.destroy = (void(*)(context_t*))destroy;
        
        this->user = 0;
-       this->db = database;
+       this->store = storage;
        this->gateway = NULL;
        
        return &this->public;
index 4235618cde042716118e90ce0caf1b1a2bd87176..53808b79456658df49f3d1312cdda5deadfdd3db 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file manager.h
- * 
- * @brief Interface of manager_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 manager manager
+ *
+ * @defgroup controller controller
+ * @ingroup manager
+ *
+ * @defgroup manager_i manager
+ * @{ @ingroup manager
  */
 
 #ifndef MANAGER_H_
 #define MANAGER_H_
 
-#include "database.h"
+#include "storage.h"
 #include "gateway.h"
 
 #include <context.h>
@@ -33,7 +38,7 @@
 typedef struct manager_t manager_t;
 
 /**
- * @brief The manager, manages multiple gateways.
+ * The manager, manages multiple gateways.
  */
 struct manager_t {
 
@@ -43,7 +48,7 @@ struct manager_t {
        context_t context;
        
        /**
-        * @brief Create an iterator over all configured gateways.
+        * Create an iterator over all configured gateways.
         *
         * enumerate() arguments: int id, char *name, int port, char *address
         * If port is 0, address is a Unix socket address.
@@ -53,7 +58,7 @@ struct manager_t {
        enumerator_t* (*create_gateway_enumerator)(manager_t *this);
        
        /**
-        * @brief Select a gateway.
+        * Select a gateway.
         *
         * If id is 0, the previously selected gateway is returned. If none has
         * been selected yet, NULL is returned.
@@ -64,7 +69,7 @@ struct manager_t {
        gateway_t* (*select_gateway)(manager_t *this, int id);
        
        /**
-        * @brief Try to log in.
+        * Try to log in.
         *
         * @param username      username
         * @param password      cleartext password
@@ -73,21 +78,21 @@ struct manager_t {
        bool (*login)(manager_t *this, char *username, char *password);
        
        /**
-        * @brief Check if user logged in.
+        * Check if user logged in.
         *
         * @return                      TRUE if logged in
         */
        bool (*logged_in)(manager_t *this);
        
        /**
-        * @brief Log out.
+        * Log out.
         */
        void (*logout)(manager_t *this);
 };
 
 /**
- * @brief Create a manager instance.
+ * Create a manager instance.
  */
-manager_t *manager_create(database_t *database);
+manager_t *manager_create(storage_t *storage);
 
-#endif /* MANAGER_H_ */
+#endif /* MANAGER_H_ @} */
diff --git a/src/manager/storage.c b/src/manager/storage.c
new file mode 100644 (file)
index 0000000..87e0374
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * 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$
+ */
+
+#include "storage.h"
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
+
+typedef struct private_storage_t private_storage_t;
+
+/**
+ * private data of storage
+ */
+struct private_storage_t {
+
+       /**
+        * public functions
+        */
+       storage_t public;
+       
+       /**
+        * database connection
+        */
+       database_t *db;
+};
+
+/**
+ * Implementation of storage_t.login.
+ */
+static int login(private_storage_t *this, char *username, char *password)
+{
+       hasher_t *hasher;
+       chunk_t hash, data;
+       size_t username_len, password_len;
+       int uid = 0;
+       char *str;
+       enumerator_t *enumerator;
+       
+       /* hash = SHA1( username | password ) */
+       hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+       if (hasher == NULL)
+       {
+               return 0;
+       }
+       hash = chunk_alloca(hasher->get_hash_size(hasher));
+       username_len = strlen(username);
+       password_len = strlen(password);
+       data = chunk_alloca(username_len + password_len);
+       memcpy(data.ptr, username, username_len);
+       memcpy(data.ptr + username_len, password, password_len);
+       hasher->get_hash(hasher, data, hash.ptr);
+       hasher->destroy(hasher);
+       str = chunk_to_hex(hash, FALSE);
+       
+       enumerator = this->db->query(this->db, 
+                       "SELECT oid FROM users WHERE username = ? AND password = ?;",
+                       DB_TEXT, username, DB_TEXT, str,
+                       DB_INT);
+       if (enumerator)
+       {
+               enumerator->enumerate(enumerator, &uid);
+               enumerator->destroy(enumerator);
+       }
+       free(str);
+       return uid;
+}
+
+/**
+ * Implementation of storage_t.create_gateway_enumerator.
+ */
+static enumerator_t* create_gateway_enumerator(private_storage_t *this, int user)
+{
+       enumerator_t *enumerator;
+       
+       enumerator = this->db->query(this->db, 
+                       "SELECT gateways.oid AS gid, name, port, address FROM "
+                       "gateways, user_gateway AS ug ON gid = ug.gateway WHERE ug.user = ?;",
+                       DB_INT, user,
+                       DB_INT, DB_TEXT, DB_INT, DB_TEXT);
+       if (!enumerator)
+       {
+               enumerator = enumerator_create_empty();
+       }
+       return enumerator;
+}
+
+/**
+ * Implementation of storage_t.destroy
+ */
+static void destroy(private_storage_t *this)
+{
+       this->db->destroy(this->db);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+storage_t *storage_create(char *uri)
+{
+       private_storage_t *this = malloc_thing(private_storage_t);
+       
+       this->public.login = (int(*)(storage_t*, char *username, char *password))login;
+       this->public.create_gateway_enumerator = (enumerator_t*(*)(storage_t*,int))create_gateway_enumerator;
+       this->public.destroy = (void(*)(storage_t*))destroy;
+       
+       this->db = lib->db->create(lib->db, uri);
+       if (this->db == NULL)
+       {
+               free(this);
+               return NULL;
+       }
+       return &this->public;
+}
+
similarity index 61%
rename from src/manager/database.h
rename to src/manager/storage.h
index 228d1cb22af2973081efa96f7243d370e3f2a467..b7439ffd18bd3fd29cab094c56bb47ed94445406 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file database.h
- * 
- * @brief Interface of database_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 storage storage
+ * @{ @ingroup manager
  */
 
-#ifndef DATABASE_H_
-#define DATABASE_H_
+#ifndef STORAGE_H_
+#define STORAGE_H_
 
 #include <utils/enumerator.h>
 
 
-typedef struct database_t database_t;
+typedef struct storage_t storage_t;
 
 /**
- * @brief Persistent database.
+ * Persistent database storage.
  */
-struct database_t {
+struct storage_t {
 
        /**
-        * @brief Try to log in using specified credentials.
+        * Try to log in using specified credentials.
         *
         * @param username                      username
         * @param password                      plaintext password
         * @return                                      user ID if login good, 0 otherwise
         */
-       int (*login)(database_t *this, char *username, char *password);
+       int (*login)(storage_t *this, char *username, char *password);
        
        /**
-        * @brief Create an iterator over the gateways.
+        * Create an iterator over the gateways.
         *
         * enumerate() arguments: int id, char *name, int port, char *address
         * If port is 0, address is a Unix socket address.
@@ -51,19 +51,19 @@ struct database_t {
         * @param user                          user Id
         * @return                                      enumerator
         */
-       enumerator_t* (*create_gateway_enumerator)(database_t *this, int user); 
+       enumerator_t* (*create_gateway_enumerator)(storage_t *this, int user);  
 
        /**
-     * @brief Destroy a database instance.
+     * Destroy a storage instance.
      */
-    void (*destroy)(database_t *this);
+    void (*destroy)(storage_t *this);
 };
 
 /**
- * @brief Create a database instance.
+ * Create a storage instance.
  *
- * @param dbfile                               SQLite database file
+ * @param uri          database connection URI
  */
-database_t *database_create(char *dbfile);
+storage_t *storage_create(char *uri);
 
-#endif /* DATABASE_H_ */
+#endif /* STORAGE_H_ @} */
similarity index 98%
rename from src/manager/lib/xml.c
rename to src/manager/xml.c
index 008235b697411b5d4f8ce5f3fa91dee3ef8be90d..17e7752ab04fcfec16e7d7c25999cf3dd47a4e30 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file xml.c
- *
- * @brief Implementation of xml_t.
- *
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
  * WITHOUT ANY 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 "xml.h"
similarity index 84%
rename from src/manager/lib/xml.h
rename to src/manager/xml.h
index 738a8e1b3be4966043c0231693d500fbc6cad078..14458a2d00234ea1b26e74be59a7fb580db2d945 100644 (file)
@@ -1,10 +1,3 @@
-/**
- * @file xml.h
- * 
- * @brief Interface of xml_t.
- * 
- */
-
 /*
  * Copyright (C) 2007 Martin Willi
  * Hochschule fuer Technik Rapperswil
  * WITHOUT ANY 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 xml xml
+ * @{ @ingroup manager
  */
 
 #ifndef XML_H_
@@ -28,7 +28,7 @@
 typedef struct xml_t xml_t;
 
 /**
- * @brief Simple enumerator based XML parser.
+ * Simple enumerator based XML parser.
  *
  * An xml_t is a single node of the XML tree, but also serves as root node
  * and therefore the document.
@@ -38,7 +38,7 @@ typedef struct xml_t xml_t;
 struct xml_t {
 
        /**
-        * @brief Create an enumerator over all children.
+        * Create an enumerator over all children.
         *
         * Enumerated values must not be manipulated or freed.
         *
@@ -47,7 +47,7 @@ struct xml_t {
        enumerator_t* (*children)(xml_t *this);
        
        /**
-        * @brief Get an attribute value by its name.
+        * Get an attribute value by its name.
         *
         * @param name          name of the attribute
         * @return                      attribute value, NULL if not found
@@ -56,8 +56,8 @@ struct xml_t {
 };
 
 /**
- * @brief Create a xml instance.
+ * Create a xml instance.
  */
 xml_t *xml_create(char *xml);
 
-#endif /* XML_H_ */
+#endif /* XML_H_ @} */
index 69902ad8f2580f6ed15edada7a15924abbff5ae0..f7125b920de6d30fc668622bdd7347cdbcc6e502 100644 (file)
@@ -123,12 +123,14 @@ if USE_NAT_TRANSPORT
 endif
 
 # This compile option activates dynamic URL fetching using libcurl
-if USE_LIBCURL
+if USE_CURL
   pluto_LDADD += -lcurl
+  AM_CFLAGS += -DLIBCURL
 endif
 
 # This compile option activates dynamic LDAP CRL fetching
-if USE_LIBLDAP
+if USE_LDAP
   pluto_LDADD += -lldap -llber
+  AM_CFLAGS += -DLIBLDAP
 endif
 
index 3a5f9839ff5c10a595ebf67bb8ed1904beda1a26..d1bce886d437ced3afa7c8da7b08c3e11e74c9ed 100644 (file)
@@ -23,11 +23,6 @@ scepclient_LDADD = asn1.o ca.o crl.o certs.o constants.o defs.o fetch.o id.o \
                    $(LIBFREESWANDIR)/libfreeswan.a $(LIBCRYPTODIR)/libcrypto.a \
                    -lgmp
 
-# This compile option activates dynamic URL fetching using libcurl
-if USE_LIBCURL
-  scepclient_LDADD += -lcurl
-endif
-
 # This compile option activates smartcard support
 if USE_SMARTCARD
   scepclient_LDADD += -ldl
index 7b4fcaabbbec7005b897a9e66c5980be0926b7d9..2520bf8dfb46cb71f8040c737a2eab20a7347a5a 100644 (file)
@@ -172,7 +172,6 @@ static const token_info_t token_info[] =
     { ARG_ENUM, offsetof(starter_config_t, setup.nat_traversal), LST_bool          },
     { ARG_TIME, offsetof(starter_config_t, setup.keep_alive), NULL                 },
     { ARG_STR,  offsetof(starter_config_t, setup.virtual_private), NULL            },
-    { ARG_STR,  offsetof(starter_config_t, setup.eapdir), 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        },
index 3f1884048bcee3a77dfb236342e7b12d34991c30..3270eab1011e3226569a94d6dfab87accc21f8dc 100644 (file)
@@ -185,7 +185,6 @@ struct starter_config {
                bool     nat_traversal;
                u_int    keep_alive;
                char     *virtual_private;
-               char     *eapdir;
                char     *pkcs11module;
                char     *pkcs11initargs;
                bool     pkcs11keepstate;
index 3da407d50a9a079ab5ad96fcd13468591acaaff5..d69b2ced288a7e77e2311390e197b2c20c90545e 100644 (file)
@@ -118,11 +118,6 @@ starter_start_charon (starter_config_t *cfg, bool debug)
     {
        arg[argc++] = "--use-syslog";
     }
-    if (cfg->setup.strictcrlpolicy)
-    {
-       arg[argc++] = "--strictcrlpolicy";
-       arg[argc++] = cfg->setup.strictcrlpolicy == STRICT_IFURI ? "2":"1";
-    }
     if (cfg->setup.cachecrls)
     {
        arg[argc++] = "--cachecrls";
@@ -133,11 +128,6 @@ starter_start_charon (starter_config_t *cfg, bool debug)
        arg[argc++] = "--crlcheckinterval";
        arg[argc++] = buffer1;
     }
-    if (cfg->setup.eapdir)
-    {
-       arg[argc++] = "--eapdir";
-       arg[argc++] = cfg->setup.eapdir;
-    }
 
     {   /* parse debug string */
        char *pos, *level, *buf_pos, type[4];
index e9fe9ec774dcfd99dac5542a6b98f226700fb379..e1957b3d84b75e4d79f9271789544343a2e217d7 100644 (file)
@@ -40,7 +40,6 @@ typedef enum {
     KW_NAT_TRAVERSAL,
     KW_KEEP_ALIVE,
     KW_VIRTUAL_PRIVATE,
-    KW_EAPDIR,
     KW_PKCS11MODULE,
     KW_PKCS11INITARGS,
     KW_PKCS11KEEPSTATE,
index 1b62937bfb49afa25b414924db3425155f26a5f2..bcadb17707998117bdfb9e969307b565997487ff 100644 (file)
@@ -49,7 +49,6 @@ nat_traversal,     KW_NAT_TRAVERSAL
 keep_alive,        KW_KEEP_ALIVE
 virtual_private,   KW_VIRTUAL_PRIVATE
 eap,               KW_EAP
-eapdir,            KW_EAPDIR
 mobike,                   KW_MOBIKE
 forceencaps,       KW_FORCEENCAPS
 pkcs11module,      KW_PKCS11MODULE
index aa4095d8c41dd52a41b357719150a683fa721394..af55961e961b45db07203bcc08b53af234ae12d1 100644 (file)
@@ -589,7 +589,7 @@ int main (int argc, char **argv)
                    }
                    if (starter_charon_pid())
                    {
-                       starter_stroke_add_conn(conn);
+                       starter_stroke_add_conn(cfg, conn);
                    }
                    if (starter_pluto_pid())
                    {
index 67e0cadcc959c613cf7e3880921cf22a1e53a87a..0ce0937b2cf3531ad9e4cc14165d5ea697a16c1f 100644 (file)
@@ -32,7 +32,7 @@
 #include <defs.h>
 #include <log.h>
 
-#include <stroke.h>
+#include <stroke_msg.h>
 
 #include "starterstroke.h"
 #include "confread.h"
@@ -175,7 +175,7 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
        msg_end->sourceip = push_string(msg, buffer);
 }
 
-int starter_stroke_add_conn(starter_conn_t *conn)
+int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
 {
        stroke_msg_t msg;
 
@@ -232,6 +232,7 @@ int starter_stroke_add_conn(starter_conn_t *conn)
        }
        msg.add_conn.mobike = conn->policy & POLICY_MOBIKE;
        msg.add_conn.force_encap = conn->policy & POLICY_FORCE_ENCAP;
+       msg.add_conn.crl_policy = cfg->setup.strictcrlpolicy;
        msg.add_conn.algorithms.ike = push_string(&msg, conn->ike);
        msg.add_conn.algorithms.esp = push_string(&msg, conn->esp);
        msg.add_conn.dpd.delay = conn->dpd_delay;
index 38fc18a46381e6bbb0e51363f1995503d3502282..8d45141ac37bdf4ad68715961581b284c4841d23 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "confread.h"
 
-extern int starter_stroke_add_conn(starter_conn_t *conn);
+extern int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn);
 extern int starter_stroke_del_conn(starter_conn_t *conn);
 extern int starter_stroke_route_conn(starter_conn_t *conn);
 extern int starter_stroke_initiate_conn(starter_conn_t *conn);
index 6ea64753c08d43a80e33fa4c35cc99cb2d958b00..aaedfc7871bd4b0bca8576f47487ebdc1ff7c00d 100644 (file)
@@ -1,9 +1,10 @@
 ipsec_PROGRAMS = stroke
 
-stroke_SOURCES = stroke.c stroke.h stroke_keywords.c stroke_keywords.h
+stroke_SOURCES = stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
 INCLUDES = -I$(top_srcdir)/src/libstrongswan
 EXTRA_DIST = stroke_keywords.txt
 MAINTAINERCLEANFILES = stroke_keywords.c
+AM_CFLAGS = -DIPSEC_PIDDIR=\"${piddir}\"
 
 stroke_keywords.c:     stroke_keywords.txt stroke_keywords.h
                $(GPERF) -C -G -t < stroke_keywords.txt > stroke_keywords.c
index 3365add54eb786bd10a9e6940b2c7f6551194bc6..6b2e33d1fdcc7f77a46851f4270d74481925992f 100644 (file)
@@ -28,7 +28,7 @@
 #include <stdio.h>
 #include <stddef.h>
 
-#include "stroke.h"
+#include "stroke_msg.h"
 #include "stroke_keywords.h"
 
 struct stroke_token {
similarity index 94%
rename from src/stroke/stroke.h
rename to src/stroke/stroke_msg.h
index 7ccddfb3e6fc6523de49e8b5cbdbd2948c42f4a6..1af3c6ec73ac7931f14b90818f299de609ca90b3 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @file stroke.h
+ * @file stroke_msg.h
  *
  * @brief Definition of stroke_msg_t.
  *
  * RCSID $Id$
  */
 
-#ifndef STROKE_H_
-#define STROKE_H_
+#ifndef STROKE_MSG_H_
+#define STROKE_MSG_H_
 
 #include <sys/types.h>
 
 /**
  * Socket which is used to communicate between charon and stroke
  */
-#define STROKE_SOCKET "/var/run/charon.ctl"
+#define STROKE_SOCKET IPSEC_PIDDIR "/charon.ctl"
 
 #define STROKE_BUF_LEN         2048
 
@@ -103,6 +103,16 @@ enum purge_flag_t {
        PURGE_OCSP =            0x0001,
 };
 
+/**
+ * CRL certificate validation policy
+ */
+typedef enum {
+       CRL_STRICT_NO,
+       CRL_STRICT_YES,
+       CRL_STRICT_IFURI,
+} crl_policy_t;
+
+
 typedef struct stroke_end_t stroke_end_t;
 
 /**
@@ -187,6 +197,7 @@ struct stroke_msg_t {
                        int mode;
                        int mobike;
                        int force_encap;
+                       crl_policy_t crl_policy;
                        struct {
                                char *ike;
                                char *esp;
@@ -246,4 +257,4 @@ struct stroke_msg_t {
        char buffer[STROKE_BUF_LEN];
 };
 
-#endif /* STROKE_H_ */
+#endif /* STROKE_MSG_H_ */
index 1a6c9d8f65b9527ee30b28bd4baa19c27011cc46..400f06c542a5e426310c0edc5a0467c34799e02c 100755 (executable)
@@ -31,7 +31,7 @@ do
        cecho " * Great, umlswitch$n is already running!"
     else
        cecho-n " * Starting umlswitch$n.."
-       uml_switch -tap tap$n -unix /tmp/umlswitch$n -daemon >/dev/null 2>&1 </dev/null
+       uml_switch -hub -tap tap$n -unix /tmp/umlswitch$n -daemon >/dev/null 2>&1 </dev/null
        sleep 2
        eval ifconfig "tap$n \$IFCONFIG_$n up"
        cgecho "done"
index 018bad0108d4bc9e742117790f4ea037eaf49088..6ef79f587782653a8d886c7049f09ed07f60fc91 100755 (executable)
@@ -57,7 +57,7 @@ do
        [ -f  $UMLHOSTFS ] || die "!! uml root file system '$UMLHOSTFS' not found"
 
        cecho-n " * Starting ${host}.."
-       eval screen -dmS ${host} "$UMLKERNEL \
+       eval screen -dmS ${host} "nice $UMLKERNEL \
            umid=${host} \
            ubda=$UMLHOSTFS \
            \$SWITCH_${host} \
index 8f9b6f49031dc5a90516250cb6c2e859fda250ec..b80323f47445609437109a87dbec0ea3b8bd3552 100755 (executable)
@@ -63,6 +63,7 @@ do
        [ -f  $UMLHOSTFS ] || die "!! uml root file system '$UMLHOSTFS' not found"
 
        cecho-n " * Starting ${host}.."
+       #eval xterm -title ${host} -geometry "+${x0}+${y0}" -rightbar -sb -sl 500 -e "gdb --args $UMLKERNEL \
        eval xterm -title ${host} -geometry "+${x0}+${y0}" -rightbar -sb -sl 500 -e "$UMLKERNEL \
            umid=${host} \
            ubda=$UMLHOSTFS \
index 508897409b2db11d0bfbc7430508709b237d257d..b1fa1e91f98f6f51e401bb65fe2104d768e814f5 100755 (executable)
@@ -17,7 +17,7 @@
 # RCSID $Id$
 
 # Root directory of testing
-UMLTESTDIR=~/strongswan-testing
+UMLTESTDIR=/home/strongswan-testing
 
 # Bzipped kernel sources
 # (file extension .tar.bz2 required)
@@ -58,7 +58,7 @@ MEM=96
 BUILDDIR=$UMLTESTDIR/umlbuild
 
 # Filename of the built UML Kernel
-UMLKERNEL=$BUILDDIR/linux-uml-$KERNELVERSION
+UMLKERNEL=$UMLTESTDIR/linux
 
 # Directory where test results will be stored
 TESTRESULTSDIR=$UMLTESTDIR/testresults
@@ -75,13 +75,13 @@ TZUML="Europe/Zurich"
 # Enable particular steps in the make-testing and
 # start-testing scripts
 #
-ENABLE_BUILD_UMLKERNEL="yes"
-ENABLE_BUILD_SSHKEYS="yes"
-ENABLE_BUILD_HOSTCONFIG="yes"
-ENABLE_BUILD_UMLROOTFS="yes"
-ENABLE_BUILD_UMLHOSTFS="yes"
-ENABLE_START_TESTING="yes"
-ENABLE_DO_TESTS="yes"
+ENABLE_BUILD_UMLKERNEL="no"
+ENABLE_BUILD_SSHKEYS="no"
+ENABLE_BUILD_HOSTCONFIG="no"
+ENABLE_BUILD_UMLROOTFS="yno"
+ENABLE_BUILD_UMLHOSTFS="yno"
+ENABLE_START_TESTING="no"
+ENABLE_DO_TESTS="no"
 ENABLE_STOP_TESTING="no"
 
 ##############################################################
@@ -92,7 +92,7 @@ ENABLE_STOP_TESTING="no"
 # Start the UML instance in a gnome-terminal (requires gnome)
 UMLSTARTMODE="gnome-terminal"
 # Start the UML instance in an xterm (requires X11R6)
-UMLSTARTMODE="xterm"
+UMLSTARTMODE="xterm"
 # Start the UML instance without a terminal window
 # but screen -r <host> can open a window anytime
 # UMLSTARTMODE="screen"
@@ -117,7 +117,7 @@ HOSTNAMEIPV4="\
 alice,10.1.0.10,192.168.0.50 \
 venus,10.1.0.20 \
 moon,192.168.0.1,10.1.0.1 \
-carol,192.168.0.100,10.3.0.1 \
+carol,192.168.0.100,10.3.0.1,10.1.0.30 \
 winnetou,192.168.0.150 \
 dave,192.168.0.200,10.3.0.2 \
 sun,192.168.0.2,10.2.0.1 \
@@ -163,7 +163,8 @@ SWITCH_alice="eth0=daemon,fe:fd:0a:01:00:0a,unix,/tmp/umlswitch1 \
 SWITCH_venus="eth0=daemon,fe:fd:0a:01:00:14,unix,/tmp/umlswitch1"
 SWITCH_moon="eth0=daemon,fe:fd:c0:a8:00:01,unix,/tmp/umlswitch0 \
              eth1=daemon,fe:fd:0a:01:00:01,unix,/tmp/umlswitch1"
-SWITCH_carol="eth0=daemon,fe:fd:c0:a8:00:64,unix,/tmp/umlswitch0"
+SWITCH_carol="eth0=daemon,fe:fd:c0:a8:00:64,unix,/tmp/umlswitch0 \
+              eth1=daemon,fe:fd:0a:01:00:22,unix,/tmp/umlswitch1"
 SWITCH_winnetou="eth0=daemon,fe:fd:c0:a8:00:96,unix,/tmp/umlswitch0"
 SWITCH_dave="eth0=daemon,fe:fd:c0:a8:00:c8,unix,/tmp/umlswitch0"
 SWITCH_sun="eth0=daemon,fe:fd:c0:a8:00:02,unix,/tmp/umlswitch0 \