aboutsummaryrefslogtreecommitdiffstats
path: root/Source/charon/sa/ike_sa.h
blob: 92c73391faf64ceb9c7b8c0c69bdd89f889762e7 (plain)
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
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
/**
 * @file ike_sa.h
 *
 * @brief Interface of ike_sa_t.
 *
 */

/*
 * Copyright (C) 2005 Jan Hutter, 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 IKE_SA_H_
#define IKE_SA_H_

#include <types.h>
#include <encoding/message.h>
#include <encoding/payloads/proposal_substructure.h>
#include <sa/ike_sa_id.h>
#include <sa/child_sa.h>
#include <sa/states/state.h>
#include <config/configuration.h>
#include <utils/logger.h>
#include <utils/randomizer.h>
#include <crypto/prfs/prf.h>
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
#include <config/connection.h>
#include <config/policy.h>

/**
 * Nonce size in bytes for nonces sending to other peer.
 * 
 * @warning Nonce size MUST be between 16 and 256 bytes.
 * 
 * @ingroup sa
 */
#define NONCE_SIZE 16


typedef struct ike_sa_t ike_sa_t;

/**
 * @brief Class ike_sa_t representing an IKE_SA. 
 * 
 * An object of this type is managed by an ike_sa_manager_t object 
 * and represents an IKE_SA. Message processing is split up in different states. 
 * They will handle all related things for the state they represent.
 * 
 * @b Constructors:
 * - ike_sa_create()
 * 
 * @ingroup sa
 */
struct ike_sa_t {

	/**
	 * @brief Processes a incoming IKEv2-Message of type message_t.
	 *
	 * @param this ike_sa_t object object
 	 * @param[in] message message_t object to process
	 * @return 				
	 * 						- SUCCESS
	 * 						- FAILED
	 * 						- DELETE_ME if this IKE_SA MUST be deleted
	 */
	status_t (*process_message) (ike_sa_t *this,message_t *message);

	/**
	 * @brief Initiate a new connection with given connection_t object.
	 * 
	 * The connection_t object is owned by the IKE_SA after the call, so
	 * do not modify or destroy it.
	 * 
	 * @param this 			calling object
	 * @param connection	connection to initiate
	 * @return				
	 * 						- SUCCESS if initialization started
	 * 						- FAILED if in wrong state
	 * 						- DELETE_ME if initialization failed and IKE_SA MUST be deleted
	 */
	status_t (*initiate_connection) (ike_sa_t *this, connection_t *connection);
	
	/**
	 * @brief Retransmits a request.
	 * 
	 * @param this 			calling object
	 * @param message_id	ID of the request to retransmit
	 * @return
	 * 						- SUCCESS
	 * 						- NOT_FOUND if request doesn't have to be retransmited
	 */
	status_t (*retransmit_request) (ike_sa_t *this, u_int32_t message_id);
	
	/**
	 * @brief Sends a request to delete IKE_SA.
	 * 
	 * Only supported in state IKE_SA_ESTABLISHED
	 * 
	 * @param this 			calling object
	 */
	void (*send_delete_ike_sa_request) (ike_sa_t *this);

	/**
	 * @brief 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 local peer address of the IKE_SA.
	 *
	 * @param this 			calling object
	 * @return 				local host_t
	 */
	host_t* (*get_my_host) (ike_sa_t *this);

	/**
	 * @brief Get remote peer address of the IKE_SA.
	 *
	 * @param this 			calling object
	 * @return 				remote host_t
	 */
	host_t* (*get_other_host) (ike_sa_t *this);
	
	/**
	 * @brief Get the state of type of associated state object.
	 *
	 * @param this 			calling object
	 * @return 				state of IKE_SA
	 */
	ike_sa_state_t (*get_state) (ike_sa_t *this);

	/**
	 * @brief Destroys a ike_sa_t object.
	 *
	 * @param this 			calling object
	 */
	void (*destroy) (ike_sa_t *this);
};


typedef struct protected_ike_sa_t protected_ike_sa_t;

/**
 * @brief Protected functions of an ike_sa_t object.
 * 
 * This members are only accessed out from 
 * the various state_t implementations.
 * 
 * @ingroup sa
 */
struct protected_ike_sa_t {

	/**
	 * Public interface of an ike_sa_t object.
	 */
	ike_sa_t public;
	
	/**
	 * @brief Build an empty IKEv2-Message and fills in default informations.
	 * 
	 * Depending on the type of message (request or response), the message id is 
	 * either message_id_out or message_id_in.
	 * 
	 * Used in state_t Implementation to build an empty IKEv2-Message.
	 * 
	 * @param this				calling object
	 * @param type				exchange type of new message
	 * @param request			TRUE, if message has to be a request
	 * @param message			new message is stored at this location
	 */
	void (*build_message) (protected_ike_sa_t *this, exchange_type_t type, bool request, message_t **message);
	
	/**
	 * @brief Get the internal stored connection_t object.
	 * 
	 * @param this 				calling object
	 * @return					pointer to the internal stored connection_t object
	 */
	connection_t *(*get_connection) (protected_ike_sa_t *this);
	
	/**
	 * @brief Set the internal connection object.
	 * 
	 * @param this 				calling object
	 * @param connection		object of type connection_t
	 */
	void (*set_connection) (protected_ike_sa_t *this, connection_t *connection);
	
	/**
	 * @brief Get the internal stored policy object.
	 * 
	 * @param this 				calling object
	 * @return					pointer to the internal stored policy_t object
	 */
	policy_t *(*get_policy) (protected_ike_sa_t *this);
	
	/**
	 * @brief Set the internal policy_t object.
	 * 
	 * @param this 				calling object
	 * @param policy			object of type policy_t
	 */
	void (*set_policy) (protected_ike_sa_t *this,policy_t *policy);
	
	/**
	 * @brief Derive all keys and create the transforms for IKE communication.
	 * 
	 * Keys are derived using the diffie hellman secret, nonces and internal
	 * stored SPIs. 
	 * Allready existing objects get destroyed.
	 * 
	 * @param this 				calling object
	 * @param proposal			proposal which contains algorithms to use
	 * @param dh				diffie hellman object with shared secret
	 * @param nonce_i			initiators nonce
	 * @param nonce_r			responders nonce
	 */
	status_t (*build_transforms) (protected_ike_sa_t *this, proposal_t* proposal,
								 diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r);
	
	/**
	 * @brief Send the next request message.
	 * 
	 * Also the first retransmit job is created.
	 * 
	 * Last stored requested message gets destroyed. Object gets not cloned!
	 * 
	 * @param this 				calling object
	 * @param message			pointer to the message which should be sent
	 * @return
	 * 							- SUCCESS
	 * 							- FAILED if message id is not next expected one
	 */
	status_t (*send_request) (protected_ike_sa_t *this,message_t * message);

	/**
	 * @brief Send the next response message.
	 * 
	 * Last stored responded message gets destroyed. Object gets not cloned!
	 * 
	 * @param this 				calling object
	 * @param message			pointer to the message which should be sent
	 * return					
	 * 							- SUCCESS
	 * 							- FAILED if message id is not next expected one
	 */
	status_t (*send_response) (protected_ike_sa_t *this,message_t * message);

	/**
	 * @brief Send a notify reply message.
	 * 
	 * @param this 				calling object
	 * @param exchange_type		type of exchange in which the notify should be wrapped
	 * @param type				type of the notify message to send
	 * @param data				notification data
	 */
	void (*send_notify) (protected_ike_sa_t *this, exchange_type_t exchange_type, notify_message_type_t type, chunk_t data);
	
	/**
	 * @brief Get the internal stored randomizer_t object.
	 * 
	 * @param this 				calling object
	 * @return					pointer to the internal randomizer_t object
	 */
	randomizer_t *(*get_randomizer) (protected_ike_sa_t *this);
	
	/**
	 * @brief Set the new state_t object of the IKE_SA object.
	 * 
	 * The old state_t object gets not destroyed. It's the callers duty to 
	 * make sure old state is destroyed (Normally the old state is the caller).
	 * 
	 * @param this 				calling object
	 * @param state				pointer to the new state_t object
	 */
	void (*set_new_state) (protected_ike_sa_t *this,state_t *state);
	
	/**
	 * @brief Set the last replied message id.
	 * 
	 * @param this 				calling object
	 * @param message_id		message id
	 */
	void (*set_last_replied_message_id) (protected_ike_sa_t *this,u_int32_t message_id);
	
	/**
	 * @brief Get the internal stored initiator crypter_t object.
	 * 
	 * @param this 				calling object
	 * @return					pointer to crypter_t object
	 */
	crypter_t *(*get_crypter_initiator) (protected_ike_sa_t *this);
	
	/**
	 * @brief Get the internal stored initiator signer_t object.
	 * 
	 * @param this 				calling object
	 * @return					pointer to signer_t object
	 */
	signer_t *(*get_signer_initiator) (protected_ike_sa_t *this);
	
	/**
	 * @brief Get the internal stored responder crypter_t object.
	 * 
	 * @param this 				calling object
	 * @return					pointer to crypter_t object
	 */
	crypter_t *(*get_crypter_responder) (protected_ike_sa_t *this);
	
	/**
	 * @brief Get the internal stored responder signer object.
	 * 
	 * @param this 				calling object
	 * @return					pointer to signer_t object
	 */
	signer_t *(*get_signer_responder) (protected_ike_sa_t *this);
	
	/**
	 * @brief Get the multi purpose prf.
	 * 
	 * @param this 				calling object
	 * @return					pointer to prf_t object
	 */
	prf_t *(*get_prf) (protected_ike_sa_t *this);
	
	/**
	 * @brief 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) (protected_ike_sa_t *this);
	
	/**
	 * @brief Get the prf used for authentication of initiator.
	 * 
	 * @param this 				calling object
	 * @return					pointer to prf_t object
	 */
	prf_t *(*get_prf_auth_i) (protected_ike_sa_t *this);
	
	/**
	 * @brief Get the prf used for authentication of responder.
	 * 
	 * @param this 				calling object
	 * @return					pointer to prf_t object
	 */
	prf_t *(*get_prf_auth_r) (protected_ike_sa_t *this);
	
	/**
	 * @brief Associates a child SA to this IKE SA
	 * 
	 * @param this 				calling object
	 * @param child_sa			child_sa to add
	 */
	void (*add_child_sa) (protected_ike_sa_t *this, child_sa_t *child_sa);
	
	/**
	 * @brief Get the last responded message.
	 *  
	 * @param this 				calling object
	 * @return					
	 * 							- last received as message_t object 
	 * 							- NULL if no last request available
	 */
	message_t *(*get_last_responded_message) (protected_ike_sa_t *this);
	
	/**
	 * @brief Get the last requested message.
	 *  
	 * @param this 				calling object
	 * @return					
	 * 							- last sent as message_t object 
	 * 							- NULL if no last request available
	 */
	message_t *(*get_last_requested_message) (protected_ike_sa_t *this);

	/**
	 * @brief Resets message counters and does destroy stored received and sent messages.
	 * 
	 * @param this 				calling object
	 */	
	void (*reset_message_buffers) (protected_ike_sa_t *this);
};


/**
 * @brief Creates an ike_sa_t object with a specific ID.
 * 
 * @warning the Content of internal ike_sa_id_t object can change over time
 * 			e.g. when a IKE_SA_INIT has been finished.
 *
 * @param[in] ike_sa_id 	ike_sa_id_t object to associate with new IKE_SA.
 *				 			The object is internal getting cloned
 *							and so has to be destroyed by the caller.
 * @return 					ike_sa_t object
 * 
 * @ingroup sa
 */
ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id);

#endif /*IKE_SA_H_*/