diff options
author | Mamadou DIOP <bossiel@yahoo.fr> | 2015-08-17 01:56:35 +0200 |
---|---|---|
committer | Mamadou DIOP <bossiel@yahoo.fr> | 2015-08-17 01:56:35 +0200 |
commit | 631fffee8a28b1bec5ed1f1d26a20e0135967f99 (patch) | |
tree | 74afe3bf3efe15aa82bcd0272b2b0f4d48c2d837 /tinyIPSec/src | |
parent | 7908865936604036e6f200f1b5e069f8752f3a3a (diff) | |
download | doubango-631fffee8a28b1bec5ed1f1d26a20e0135967f99.zip doubango-631fffee8a28b1bec5ed1f1d26a20e0135967f99.tar.gz |
-
Diffstat (limited to 'tinyIPSec/src')
-rw-r--r-- | tinyIPSec/src/tinyipsec_config.h | 83 | ||||
-rw-r--r-- | tinyIPSec/src/tipsec.c | 328 | ||||
-rw-r--r-- | tinyIPSec/src/tipsec.h | 347 |
3 files changed, 758 insertions, 0 deletions
diff --git a/tinyIPSec/src/tinyipsec_config.h b/tinyIPSec/src/tinyipsec_config.h new file mode 100644 index 0000000..4c2b564 --- /dev/null +++ b/tinyIPSec/src/tinyipsec_config.h @@ -0,0 +1,83 @@ +/* Copyright (C) 2010-2014 Mamadou DIOP +* Copyright (C) 2011-2014 Doubango Telecom <http://www.doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +*/ +#ifndef TINYIPSEC_CONFIG_H +#define TINYIPSEC_CONFIG_H + +#ifdef __SYMBIAN32__ +#undef _WIN32 /* Because of WINSCW */ +#endif + +// Windows (XP/Vista/7/CE and Windows Mobile) macro definition +#if defined(WIN32)|| defined(_WIN32) || defined(_WIN32_WCE) +# define TIPSEC_UNDER_WINDOWS 1 +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define TIPSEC_UNDER_WINDOWS_RT 1 +# endif +#endif + +/* Used on Windows and Symbian systems to export/import public functions and global variables. +*/ +#if !defined(__GNUC__) && defined(TINYIPSEC_EXPORTS) +# define TINYIPSEC_API __declspec(dllexport) +# define TINYIPSEC_GEXTERN __declspec(dllexport) +#elif !defined(__GNUC__) && !defined(TINYIPSEC_IMPORTS_IGNORE) +# define TINYIPSEC_API __declspec(dllimport) +# define TINYIPSEC_GEXTERN __declspec(dllimport) +#else +# define TINYIPSEC_API +# define TINYIPSEC_GEXTERN extern +#endif + +/* Guards against C++ name mangling +*/ +#ifdef __cplusplus +# define TIPSEC_BEGIN_DECLS extern "C" { +# define TIPSEC_END_DECLS } +#else +# define TIPSEC_BEGIN_DECLS +# define TIPSEC_END_DECLS +#endif + +/* Disable some well-known warnings +*/ +#ifdef _MSC_VER +# define _CRT_SECURE_NO_WARNINGS +# pragma warning( disable : 4996 ) +#endif + +// +// IPSEC +// +#if HAVE_IPSEC +# if (_WIN32_WINNT >= 0x0600) +# define HAVE_IPSEC_VISTA 1 +# elif (_WIN32_WINNT >= 0x0501) +# define HAVE_IPSEC_XP 0 +# elif HAVE_IPSEC_TOOLS +# define HAVE_IPSEC_RACOON 1 +# endif +#endif + + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#endif /* TINYIPSEC_CONFIG_H */ + diff --git a/tinyIPSec/src/tipsec.c b/tinyIPSec/src/tipsec.c new file mode 100644 index 0000000..2fe9976 --- /dev/null +++ b/tinyIPSec/src/tipsec.c @@ -0,0 +1,328 @@ +/* Copyright (C) 2010-2014 Mamadou DIOP +* Copyright (C) 2011-2014 Doubango Telecom <http://www.doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +*/ + +/**@file tipsec.c + * @brief IPSec plugin and context managers. + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + */ +#include "tipsec.h" + +#include "tsk_plugin.h" +#include "tsk_debug.h" + +/** Max number of plugins (consumer types) we can create */ +#if !defined(TIPSEC_MAX_PLUGINS) +# define TIPSEC_MAX_PLUGINS 0x04 +#endif /* TIPSEC_MAX_PLUGINS */ + +/* pointer to all registered consumers */ +static const tipsec_plugin_def_t* __tipsec_plugins[TIPSEC_MAX_PLUGINS] = { tsk_null }; + +/** +* Create an IPSec context to manage the SAs. +* Before calling this function at least one special implementation must be registered using @ref tipsec_plugin_register_static(). +* @param ipproto IPSec internet protocol. +* @param use_ipv6 Whether to use IPv6 or not (IPv4). +* @param mode IPSec mode. +* @param ealg IPSec encryption algorithm. +* @param alg IPSec algorithm. +* @param protocol IPSec protocol. +* @param pp_ctx Pointer holding the newly created context. Valid only if the retured code is @ref tipsec_error_success. This object must be destroyed using @a TSK_OBJECT_SAFE_FREE(). +* @retval @ref tipsec_error_success if no error; otherwise error code. +*/ +tipsec_error_t tipsec_ctx_create( + tipsec_ipproto_t ipproto, + tsk_bool_t use_ipv6, + tipsec_mode_t mode, + tipsec_ealg_t ealg, + tipsec_alg_t alg, + tipsec_proto_t protocol, + tipsec_ctx_t** pp_ctx) +{ + tipsec_error_t err = tipsec_error_success; + tsk_size_t i = 0; + const tipsec_plugin_def_t* pc_plugin = tsk_null; + tipsec_ctx_t* p_ctx = tsk_null; + + if (!pp_ctx || *pp_ctx) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tipsec_error_invalid_param; + } + + // Create the context using the plugins registry + while ((i < TIPSEC_MAX_PLUGINS) && (pc_plugin = __tipsec_plugins[i++])) { + if (pc_plugin->objdef) { + if ((p_ctx = tsk_object_new(pc_plugin->objdef))) { + /* initialize the newly IPSec context */ + p_ctx->pc_plugin = pc_plugin; + p_ctx->initialized = 0; + p_ctx->started = 0; + p_ctx->state = tipsec_state_initial; + p_ctx->use_ipv6 = use_ipv6; + p_ctx->mode = mode; + p_ctx->ealg = ealg; + p_ctx->alg = alg; + p_ctx->protocol = protocol; + p_ctx->ipproto = ipproto; + break; + } + } + } + + if (!pc_plugin || !p_ctx) { + TSK_DEBUG_ERROR("Failed to find/create a plugin instance"); + return tipsec_error_notfound; + } + + // Initialize the newly created context + err = pc_plugin->init(p_ctx); + if (err) { + goto bail; + } + +bail: + if (err) { + TSK_OBJECT_SAFE_FREE(p_ctx); + } + *pp_ctx = p_ctx; + return err; +} + +/** +* Ensure the SAs. This function must be called before sending/receiving any data. +* @param p_ctx Pointer to a context created using @ref tipsec_ctx_create(). +* @retval @ref tipsec_error_success if no error; otherwise error code. +*/ +tipsec_error_t tipsec_ctx_start(tipsec_ctx_t* p_ctx) +{ + if (!p_ctx || !p_ctx->pc_plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tipsec_error_invalid_param; + } + if (!p_ctx->initialized || p_ctx->state != tipsec_state_full) { + TSK_DEBUG_ERROR("Invalid state (not initialized or not in full state)"); + return tipsec_error_invalid_state; + } + return p_ctx->pc_plugin->start(p_ctx); +} + +/** +* Set local information. On windows Vista and later this function must be called to request local SPIs. +* @param p_ctx Pointer to a context created using @ref tipsec_ctx_create(). +* @param addr_local Local IP address (e.g. "192.168.0.5"). The IP version depends on whether @a use_param (0 or 1) when @ref tipsec_ctx_create() was used to create the context. +* @param addr_remote Remote IP address (e.g. "192.168.0.5"). The IP version depends on whether @a use_param (0 or 1) when @ref tipsec_ctx_create() was used to create the context. +* @param port_uc Local client port used to send data. Must be within [1024-65535]. +* @param port_us Local server port used to received data. Must be within [1024-65535]. +* @retval @ref tipsec_error_success if no error; otherwise error code. +*/ +tipsec_error_t tipsec_ctx_set_local(tipsec_ctx_t* p_ctx, const char* addr_local, const char* addr_remote, tipsec_port_t port_uc, tipsec_port_t port_us) +{ + if (!p_ctx || !p_ctx->pc_plugin || !addr_local || !addr_remote || port_uc < 1024 || port_us < 1024) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tipsec_error_invalid_param; + } + if (!p_ctx->initialized || p_ctx->state != tipsec_state_initial) { + TSK_DEBUG_ERROR("Invalid state (not initialized or not in initial state)"); + return tipsec_error_invalid_state; + } + return p_ctx->pc_plugin->set_local(p_ctx, addr_local, addr_remote, port_uc, port_us); +} + +/** +* Set Integrity (IK) and Confidentiality (CK) Keys. +* On the UE, the IK and CK are built using the "nonce" value using the 494 from the P-CSCF which means the function must be called after the REGISTER<->494 round trip. +* @param p_ctx Pointer to a context created using @ref tipsec_ctx_create(). +* @param ik The Integrity Key. +* @param ck The Confidentiality Key. +* @retval @ref tipsec_error_success if no error; otherwise error code. +*/ +tipsec_error_t tipsec_ctx_set_keys(tipsec_ctx_t* p_ctx, const tipsec_key_t* ik, const tipsec_key_t* ck) +{ + if (!p_ctx || !p_ctx->pc_plugin || !ik || !ck) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tipsec_error_invalid_param; + } + return p_ctx->pc_plugin->set_keys(p_ctx, ik, ck); +} + +/** +* Set the remote information. +* @param p_ctx Pointer to a context created using @ref tipsec_ctx_create(). +* @param spi_pc Remote client SPI (Security Parameter Index) used by the remote party to send data. +* @param spi_ps Remote server SPI (Security Parameter Index) used by the remote party to receive data. +* @param port_pc Remote client port used by the remote party to send data. Must be within [1024-65535]. +* @param port_ps Remote server port used by the remote party to receive data. Must be within [1024-65535]. +* @param lifetime The SA lifetime (in seconds). Must not be null. Should be 2xSipRegistrationTimeout. On Windows vista and later, the maximum allowed value is @a 172799 seconds. +* @retval @ref tipsec_error_success if no error; otherwise error code. +*/ +tipsec_error_t tipsec_ctx_set_remote(tipsec_ctx_t* p_ctx, tipsec_spi_t spi_pc, tipsec_spi_t spi_ps, tipsec_port_t port_pc, tipsec_port_t port_ps, tipsec_lifetime_t lifetime) +{ + if (!p_ctx || !p_ctx->pc_plugin || port_pc < 1024 || port_ps < 1024 || !lifetime) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tipsec_error_invalid_param; + } + if (!p_ctx->initialized || p_ctx->state != tipsec_state_inbound) { + TSK_DEBUG_ERROR("Invalid state (not initialized or not in initial state)"); + return tipsec_error_invalid_state; + } + return p_ctx->pc_plugin->set_remote(p_ctx, spi_pc, spi_ps, port_pc, port_ps, lifetime); +} + +/** +* Shutdown all SAs associated to this context. It's no longer allowed to send/recv data after calling this function. +* @param p_ctx Pointer to a context created using @ref tipsec_ctx_create(). +* @retval @ref tipsec_error_success if no error; otherwise error code. +*/ +tipsec_error_t tipsec_ctx_stop(tipsec_ctx_t* p_ctx) +{ + if (!p_ctx || !p_ctx->pc_plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tipsec_error_invalid_param; + } + return p_ctx->pc_plugin->stop(p_ctx); +} + +/** +* Register an IPSec special implementation (e.g. Windows XP, Windows Vista or Linux IPSec-Tools) using a static definition. +* @param pc_plugin pointer to the static definition. +* @retval @ref tipsec_error_success if no error; otherwise error code. +* @sa @ref tipsec_plugin_unregister_static(), @ref tipsec_plugin_unregister_file() +*/ +tipsec_error_t tipsec_plugin_register_static(const tipsec_plugin_def_t* pc_plugin) +{ + tsk_size_t i; + if (!pc_plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tipsec_error_invalid_param; + } + + /* add or replace the plugin */ + for (i = 0; i < TIPSEC_MAX_PLUGINS; ++i) { + if (!__tipsec_plugins[i] || (__tipsec_plugins[i] == pc_plugin)) { + __tipsec_plugins[i] = pc_plugin; + TSK_DEBUG_INFO("Register IPSec implementation: %s", pc_plugin->desc); + return tipsec_error_success; + } + } + + TSK_DEBUG_ERROR("There are already %d plugins.", TIPSEC_MAX_PLUGINS); + return tipsec_error_outofbound; +} + +/** +* UnRegister an IPSec special implementation (e.g. Windows XP, Windows Vista or Linux IPSec-Tools) using a static definition. +* @param pc_plugin pointer to the static definition. +* @retval @ref tipsec_error_success if no error; otherwise error code. +* @sa @ref tipsec_plugin_register_static(), @ref tipsec_plugin_register_file() +*/ +tipsec_error_t tipsec_plugin_unregister_static(const tipsec_plugin_def_t* pc_plugin) +{ + tsk_size_t i; + tsk_bool_t b_found = tsk_false; + + if (!pc_plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tipsec_error_invalid_param; + } + + /* find the plugin to unregister */ + for (i = 0; i < TIPSEC_MAX_PLUGINS && __tipsec_plugins[i]; ++i) { + if (__tipsec_plugins[i] == pc_plugin) { + __tipsec_plugins[i] = tsk_null; + b_found = tsk_true; + TSK_DEBUG_INFO("UnRegister IPSec implementation: %s", pc_plugin->desc); + break; + } + } + + /* compact */ + if (b_found) { + for (; i < (TIPSEC_MAX_PLUGINS - 1); ++i) { + if (__tipsec_plugins[i+1]) { + __tipsec_plugins[i] = __tipsec_plugins[i + 1]; + } + else { + break; + } + } + __tipsec_plugins[i] = tsk_null; + } + return (b_found ? tipsec_error_success : tipsec_error_notfound); +} + +/** +* Register an IPSec special implementation (e.g. Windows XP, Windows Vista or Linux IPSec-Tools) using a shared library (*.DLL, *.SO). +* @param pc_filepath Path to the plugin. +* @param pp_plugin Pointer to the newly created plugin. You must call @ref tipsec_plugin_unregister_file() when you no longer need to use the plugin. +* @retval @ref tipsec_error_success if no error; otherwise error code. +* @sa @ref tipsec_plugin_unregister_static(), @ref tipsec_plugin_unregister_file() +*/ +tipsec_error_t tipsec_plugin_register_file(const char* pc_filepath, struct tsk_plugin_s** pp_plugin) +{ + struct tsk_plugin_s* p_plugin = tsk_null; + tsk_plugin_def_ptr_const_t p_def; + tipsec_error_t err = tipsec_error_success; + int i = 0, count = 0; + + p_plugin = tsk_plugin_create(pc_filepath); + if (!p_plugin) { + return tipsec_error_notfound; + } + + while ((p_def = tsk_plugin_get_def_2(p_plugin, tsk_plugin_def_type_ipsec, tsk_plugin_def_media_type_all, i++))) { + if (p_def) { + err = tipsec_plugin_register_static(p_def); + if (!err) { + ++count; + } + } + } + + if (count <= 0) { + TSK_DEBUG_ERROR("No plugin in %s", pc_filepath); + TSK_OBJECT_SAFE_FREE(p_plugin); + return tipsec_error_notfound; + } + + *pp_plugin = p_plugin; + return err; +} + +/** +* UnRegister an IPSec special implementation (e.g. Windows XP, Windows Vista or Linux IPSec-Tools). +* @param p_plugin Pointer to the plugin previously registered using @ref tipsec_plugin_register_file(). +* @retval @ref tipsec_error_success if no error; otherwise error code. +* @sa @ref tipsec_plugin_unregister_static(), @ref tipsec_plugin_unregister_file() +*/ +tipsec_error_t tipsec_plugin_unregister_file(struct tsk_plugin_s* p_plugin) +{ + int i = 0; + tsk_plugin_def_ptr_const_t p_def; + if (!p_plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return tipsec_error_invalid_param; + } + while ((p_def = tsk_plugin_get_def_2(p_plugin, tsk_plugin_def_type_ipsec, tsk_plugin_def_media_type_all, i++))) { + if (p_def) { + tipsec_plugin_unregister_static(p_def); + } + } + return tipsec_error_success; +} diff --git a/tinyIPSec/src/tipsec.h b/tinyIPSec/src/tipsec.h new file mode 100644 index 0000000..5c4c5e5 --- /dev/null +++ b/tinyIPSec/src/tipsec.h @@ -0,0 +1,347 @@ +/* Copyright (C) 2010-2014 Mamadou DIOP +* Copyright (C) 2011-2014 Doubango Telecom <http://www.doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +*/ + +/**@file tipsec.h + * @brief IPSec plugin and context managers. + * + * @author Mamadou Diop <diopmamadou(at)doubango[dot]org> + */ +#ifndef TINYIPSEC_IPSEC_H +#define TINYIPSEC_IPSEC_H + +#include "tinyipsec_config.h" + +#include "tsk_string.h" + +TIPSEC_BEGIN_DECLS + +// Forward declaration +struct tsk_plugin_s; + +/** Converts any IPSec context (XP, Vista, Linux IPSec-Tools ...) to the common IPSec context. +* @param self The context to convert. MUST be declared using @ref TIPSEC_DECLARE_CTX. +* @retval A pointer to @ref tipsec_ctx_t. +*/ +#define TIPSEC_CTX(self) ((tipsec_ctx_t*)(self)) + +/**@def TIPSEC_IPPROTO_FROM_STR +* Converts IPSec IP protocol string to enum value. +* @param str_ipproto Must be "tcp", "udp" or "icmp" +* @retval @ref tipsec_ipproto_t value. +*/ +/**@def TIPSEC_IPPROTO_TO_STR +* Converts IPSec IP protocol enum to string value. +* @param enum_ipproto @ref tipsec_ipproto_t value. +* @retval "tcp", "udp" or "icmp" string value. +*/ +#define TIPSEC_IPPROTO_FROM_STR(str_ipproto) (tsk_strequals(str_ipproto, "tcp") ? tipsec_ipproto_tcp : (tsk_strequals(str_ipproto, "icmp") ? tipsec_ipproto_icmp : tipsec_ipproto_udp)) +#define TIPSEC_IPPROTO_TO_STR(enum_ipproto) (enum_ipproto == tipsec_ipproto_tcp ? "tcp" : (enum_ipproto == tipsec_ipproto_icmp ? "icmp" : "udp")) + + +/**@def TIPSEC_MODE_FROM_STR +* Converts IPSec mode string to enum value. +* @param str_mode Must be "tun" (tunnel) or "trans" (transport). +* @retval @ref tipsec_mode_t value. +*/ +/**@def TIPSEC_MODE_TO_STR +* Converts IPSec mode enum to string value. +* @param enum_mode @ref tipsec_mode_t value. +* @retval "tun" (tunnel) or "trans" (transport) string value. +*/ +#define TIPSEC_MODE_FROM_STR(str_mode) (tsk_strequals(str_mode, "tun") ? tipsec_mode_tun : tipsec_mode_trans) +#define TIPSEC_MODE_TO_STR(enum_mode) (enum_mode == tipsec_mode_tun ? "tun" : "trans") + +/** @def TIPSEC_EALG_FROM_STR +* Converts IPSec encryption algorithm string to enum value. +* @param str_ealg Must be "des-ede3-cbc", "aes" or "null". +* @retval @ref tipsec_ealg_t value. +*/ +/**@def TIPSEC_EALG_TO_STR +* Converts IPSec encryption algorithm enum to string value. +* @param enum_ealg @ref tipsec_ealg_t value. +* @retval "des-ede3-cbc", "aes" or "null" string value. +*/ +#define TIPSEC_EALG_FROM_STR(str_ealg) (tsk_strequals(str_ealg, "des-ede3-cbc") ? tipsec_ealg_des_ede3_cbc : (tsk_strequals(str_ealg, "aes-cbc") ? tipsec_ealg_aes : tipsec_ealg_null)) +#define TIPSEC_EALG_TO_STR(enum_ealg) (enum_ealg == tipsec_ealg_des_ede3_cbc ? "des-ede3-cbc" : (enum_ealg == tipsec_ealg_aes ? "aes-cbc" : "null")) + + +/** @def TIPSEC_ALG_FROM_STR +* Converts IPSec algorithm string to enum value. +* @param str_alg Must be "hmac-sha-1-96" or "hmac-md5-96". +* @retval @ref tipsec_alg_t value. +*/ +/**@def TIPSEC_ALG_TO_STR +* Converts IPSec algorithm enum to string value. +* @param enum_alg @ref tipsec_alg_t value. +* @retval "hmac-sha-1-96" or "hmac-md5-96" string value. +*/ +#define TIPSEC_ALG_FROM_STR(str_alg) (tsk_strequals(str_alg, "hmac-sha-1-96") ? tipsec_alg_hmac_sha_1_96 : tipsec_alg_hmac_md5_96) +#define TIPSEC_ALG_TO_STR(enum_alg) (enum_alg == tipsec_alg_hmac_sha_1_96 ? "hmac-sha-1-96" : "hmac-md5-96") + +/**@def TIPSEC_PROTOCOL_FROM_STR +* Converts IPSec protocol string to enum value. +* @param str_protocol Must be "ah", "esp" or "ah/esp". +* @retval @ref tipsec_proto_t value. +*/ +/**@def TIPSEC_PROTOCOL_TO_STR +* Converts IPSec protocol enum to string value. +* @param enum_protocol @ref tipsec_proto_t value. +* @retval "ah", "esp" or "ah/esp" string value. +*/ +#define TIPSEC_PROTOCOL_FROM_STR(str_protocol) (tsk_strequals(str_protocol, "ah") ? tipsec_proto_ah : ((tsk_strequals(str_protocol, "ah/esp")) ? tipsec_proto_both : tipsec_proto_esp)) +#define TIPSEC_PROTOCOL_TO_STR(enum_protocol) (enum_protocol == tipsec_proto_ah ? "ah" : (enum_protocol == tipsec_proto_both ? "ah/esp" : "esp")) + +/**@def TIPSEC_KEY_LEN +* Default size for IK (Integrity Key) and CK (Confidentiality Key). +**/ +/**@def TIPSEC_CK_LEN +* Size of CK (Confidentiality Key). +*/ +/**@def TIPSEC_IK_LEN +* Size of IK (Integrity Key). +*/ +#define TIPSEC_KEY_LEN 16 +#define TIPSEC_IK_LEN 20 +#define TIPSEC_CK_LEN 24 + +/**@def tipsec_lifetime_t +*/ +/**@def tipsec_spi_t +*/ +/**@def tipsec_port_t +*/ +/**@def tipsec_key_t +*/ +typedef uint64_t tipsec_lifetime_t; +typedef uint32_t tipsec_spi_t; +typedef uint16_t tipsec_port_t; +typedef void tipsec_key_t; + +/**@ingroup tipsec_common_group + * List of IPSec modes. +**/ +typedef enum tipsec_mode_e { + //! IPSec transport mode. + tipsec_mode_trans, + //! IPSec tunneling mode. + tipsec_mode_tun +} +tipsec_mode_t; + +/** List of supported IPSec protocols. +**/ +typedef enum tipsec_proto_e { + //! AH protocol ("ah"). + tipsec_proto_ah = (0x01 << 0), + //! ESP protocol ("esp"). + tipsec_proto_esp = (0x01 << 1), + //! Both AH and ESP protocols ("ah/esp"). + tipsec_proto_both = (tipsec_proto_ah | tipsec_proto_esp) +} +tipsec_proto_t; + +/**List of supported Internet protocols for IPSec. +**/ +typedef enum tipsec_ipproto_e { + //! UDP. + tipsec_ipproto_udp, + //! TCP. + tipsec_ipproto_tcp, + //! ICMP. + tipsec_ipproto_icmp, + //! ALL IP protocols + tipsec_ipproto_all +} +tipsec_ipproto_t; + +/**List of IPSec IPSec algorithms. +**/ +typedef enum tipsec_alg_e { + //! "hmac-md5-96" algorithm. + tipsec_alg_hmac_md5_96, + //! "hmac-sha-1-96" algorithm. + tipsec_alg_hmac_sha_1_96 +} +tipsec_alg_t; + +/**List of supported IPSec encryption algorithms. +**/ +typedef enum tipsec_ealg_e { + //! "des-ede3-cbc" encryption algorithm. + tipsec_ealg_des_ede3_cbc, + //! "aes" encryption algorithm. + tipsec_ealg_aes, + //! "null" encryption algorithm. + tipsec_ealg_null +} +tipsec_ealg_t; + +/** List of IPSec states. +**/ +typedef enum tipsec_state_e { + //! The default state. At this state no SA is created. It's the first and default state. + tipsec_state_initial, + //! Partial state. At this state only inbound SAs (with their SPIs) have been created. + tipsec_state_inbound, + //! Full state. At this state both inbound and outbound SAs have been create. It's the final state. + tipsec_state_full, + //! All SAs are in active mode. + tipsec_state_active +} +tipsec_state_t; + +/** List of supported IPSec errors +*/ +typedef enum tipsec_error_e { + tipsec_error_success = 0, /**< Success */ + tipsec_error_invalid_param, /**< Invalid parameter */ + tipsec_error_invalid_state, /**< Invalid state */ + tipsec_error_access_violation, /**< Access violation */ + tipsec_error_permission_denied, /**< Permission denied */ + tipsec_error_outofmemory, /**< Out of memory */ + tipsec_error_outofbound, /**< Out of bound */ + tipsec_error_notfound, /**< Not found */ + tipsec_error_notimplemented, /**< Not implemented */ + tipsec_error_sys, /**< System error */ +} +tipsec_error_t; + +/** List of supported IPSec implementations +*/ +typedef enum tipsec_impl_type_e { + //! Windows XP only. This implementation works with IPv6 only. + tipsec_impl_type_xp, + //! Windows Vista or later. Using Windows Filtering Platform (http://msdn.microsoft.com/en-us/windows/hardware/gg463267.aspx). + tipsec_impl_type_vista, + //! Linux IPSec tools (http://ipsec-tools.sourceforge.net/) + tipsec_impl_type_ltools, +} +tipsec_impl_type_t; + +/** +* Base IPSec context wrapping special implementation. +* An instance of this object must be created using @ref tipsec_ctx_create() and destroyed using @ref TSK_OBJECT_SAFE_FREE(). +*/ +typedef struct tipsec_ctx_s { + TSK_DECLARE_OBJECT; + + //! Indicates whether the context have been initialized or not. + unsigned initialized; + //! Indicates whether the context have been started or not. + unsigned started:1; + + //! The current state of the IPSec context. + tipsec_state_t state; + + //! Indicates whether to use IPv6 addresses or not. + unsigned use_ipv6:1; + //! The network protocol. + tipsec_ipproto_t ipproto; + + //! IPSec mode. + tipsec_mode_t mode; + //! Encrypt algorithm (). + tipsec_ealg_t ealg; + //! Algorithm. + tipsec_alg_t alg; + //! IPSec protocol. + tipsec_proto_t protocol; + + //! Remote address (Proxy-CSCF). + void* addr_remote; + //! Proxy-CSCF client SPI (Security Parameter Index). + tipsec_spi_t spi_pc; + //! Proxy-CSCF server SPI (Security Parameter Index). + tipsec_spi_t spi_ps; + //! Proxy-CSCF client port. + tipsec_port_t port_pc; + //! Proxy-CSCF server port. + tipsec_port_t port_ps; + + //! Local address (UE). + void* addr_local; + //! UE client SPI (Security Parameter Index). On Windows Vista and later it's up to the OS to set this value. + tipsec_spi_t spi_uc; + //! UE server SPI (Security Parameter Index). On Windows Vista and later it's up to the OS to set this value. + tipsec_spi_t spi_us; + //! UE client port. + tipsec_port_t port_uc; + //! UE server port. + tipsec_port_t port_us; + + //! The confidentiality key. + tipsec_key_t *ck; + //! The integrity key. + tipsec_key_t *ik; + + //! reg-await-auth timer value (in seconds). + tipsec_lifetime_t lifetime; + + //! Reference to the plugin used to create this context. + const struct tipsec_plugin_def_s* pc_plugin; +} +tipsec_ctx_t; + +/** Declare a struct as a context. Used to simulate inheritence. */ +#define TIPSEC_DECLARE_CTX tipsec_ctx_t __ipsec_ctx__ + +/** Virtual table used to define a special IPSec implentation (XP, Vista or Linux IPSec Tools) plugin */ +typedef struct tipsec_plugin_def_s { + //! object definition used to create an instance of the special implementation + const tsk_object_def_t* objdef; + + //! the type of the consumer + enum tipsec_impl_type_e type; + //! full description (usefull for debugging) + const char* desc; + + tipsec_error_t (* init) (tipsec_ctx_t* ); + tipsec_error_t (* set_local) (tipsec_ctx_t* , const char* addr_local, const char* addr_remote, tipsec_port_t port_uc, tipsec_port_t port_us); + tipsec_error_t (* set_remote) (tipsec_ctx_t* , tipsec_spi_t spi_pc, tipsec_spi_t spi_ps, tipsec_port_t port_pc, tipsec_port_t port_ps, tipsec_lifetime_t lifetime); + tipsec_error_t (* set_keys) (tipsec_ctx_t* , const tipsec_key_t* ik, const tipsec_key_t* ck); + tipsec_error_t (* start) (tipsec_ctx_t* ); + tipsec_error_t (* stop) (tipsec_ctx_t* ); +} +tipsec_plugin_def_t; + + +TINYIPSEC_API tipsec_error_t tipsec_ctx_create( + tipsec_ipproto_t ipproto, + tsk_bool_t use_ipv6, + tipsec_mode_t mode, + tipsec_ealg_t ealg, + tipsec_alg_t alg, + tipsec_proto_t protocol, + tipsec_ctx_t** pp_ctx); +TINYIPSEC_API tipsec_error_t tipsec_ctx_start(tipsec_ctx_t* p_ctx); +TINYIPSEC_API tipsec_error_t tipsec_ctx_set_local(tipsec_ctx_t* p_ctx, const char* addr_local, const char* addr_remote, tipsec_port_t port_uc, tipsec_port_t port_us); +TINYIPSEC_API tipsec_error_t tipsec_ctx_set_keys(tipsec_ctx_t* p_ctx, const tipsec_key_t* ik, const tipsec_key_t* ck); +TINYIPSEC_API tipsec_error_t tipsec_ctx_set_remote(tipsec_ctx_t* p_ctx, tipsec_spi_t spi_pc, tipsec_spi_t spi_ps, tipsec_port_t port_pc, tipsec_port_t port_ps, tipsec_lifetime_t lifetime); +TINYIPSEC_API tipsec_error_t tipsec_ctx_stop(tipsec_ctx_t* p_ctx); + +TINYIPSEC_API tipsec_error_t tipsec_plugin_register_static(const tipsec_plugin_def_t* pc_plugin); +TINYIPSEC_API tipsec_error_t tipsec_plugin_unregister_static(const tipsec_plugin_def_t* pc_plugin); +TINYIPSEC_API tipsec_error_t tipsec_plugin_register_file(const char* pc_filepath, struct tsk_plugin_s** pp_plugin); +TINYIPSEC_API tipsec_error_t tipsec_plugin_unregister_file(struct tsk_plugin_s* pp_plugin); + + + +TIPSEC_END_DECLS + +#endif /* TINYIPSEC_IPSEC_H */ |