doubango/tinyIPSec/src/tipsec.h
c732d49e
 /* 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 */