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