1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
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 */
|