914da1e7409dab9ae14468f58b1481f0ac7edb74
[strongswan.git] / Source / charon / sa / ike_sa.c
1 /**
2 * @file ike_sa.c
3 *
4 * @brief Class ike_sa_t. An object of this type is managed by an
5 * ike_sa_manager_t object and represents an IKE_SA
6 *
7 */
8
9 /*
10 * Copyright (C) 2005 Jan Hutter, Martin Willi
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include "ike_sa.h"
25
26 #include <types.h>
27 #include <globals.h>
28 #include <definitions.h>
29 #include <utils/allocator.h>
30 #include <utils/linked_list.h>
31 #include <utils/logger_manager.h>
32 #include <utils/randomizer.h>
33 #include <transforms/diffie_hellman.h>
34 #include <transforms/prf_plus.h>
35 #include <transforms/crypters/crypter.h>
36 #include <encoding/payloads/sa_payload.h>
37 #include <encoding/payloads/nonce_payload.h>
38 #include <encoding/payloads/ke_payload.h>
39 #include <encoding/payloads/transform_substructure.h>
40 #include <encoding/payloads/transform_attribute.h>
41 #include <sa/states/initiator_init.h>
42 #include <sa/states/responder_init.h>
43 #include <queues/jobs/delete_ike_sa_job.h>
44
45
46
47
48 typedef struct private_ike_sa_t private_ike_sa_t;
49
50 /**
51 * Private data of an ike_sa_t object.
52 */
53 struct private_ike_sa_t {
54
55 /**
56 * Protected part of a ike_sa_t object.
57 */
58 protected_ike_sa_t protected;
59
60
61 /**
62 * Creates a job to delete the given IKE_SA.
63 *
64 * @param this calling object
65 */
66 status_t (*create_delete_job) (private_ike_sa_t *this);
67
68 /**
69 * Resends the last sent reply.
70 *
71 * @param this calling object
72 */
73 status_t (*resend_last_reply) (private_ike_sa_t *this);
74
75 /* private values */
76
77 /**
78 * Identifier for the current IKE_SA
79 */
80 ike_sa_id_t *ike_sa_id;
81
82 /**
83 * Linked List containing the child sa's of the current IKE_SA
84 */
85 linked_list_t *child_sas;
86
87 /**
88 * Current state of the IKE_SA
89 */
90 state_t *current_state;
91
92 /**
93 * this SA's source for random data
94 */
95 randomizer_t *randomizer;
96
97 /**
98 * contains the last responded message
99 *
100 */
101 message_t *last_responded_message;
102
103 /**
104 * contains the last requested message
105 *
106 */
107 message_t *last_requested_message;
108
109 /**
110 * Informations of this host
111 */
112 struct {
113 host_t *host;
114 } me;
115
116 /**
117 * Informations of the other host
118 */
119 struct {
120 host_t *host;
121 } other;
122
123 /**
124 * Crypter object for initiator
125 */
126 crypter_t *crypter_initiator;
127
128 /**
129 * Crypter object for responder
130 */
131 crypter_t *crypter_responder;
132
133 /**
134 * Signer object for initiator
135 */
136 signer_t *signer_initiator;
137
138 /**
139 * Signer object for responder
140 */
141 signer_t *signer_responder;
142
143 /**
144 * prf function
145 */
146 prf_t *prf;
147
148
149
150 /**
151 * Shared secrets
152 */
153 struct {
154 /**
155 * Key used for deriving other keys
156 */
157 chunk_t d_key;
158
159 /**
160 * Key for authenticate (initiator)
161 */
162 chunk_t ai_key;
163
164 /**
165 * Key for authenticate (responder)
166 */
167 chunk_t ar_key;
168
169 /**
170 * Key for encryption (initiator)
171 */
172 chunk_t ei_key;
173
174 /**
175 * Key for encryption (responder)
176 */
177 chunk_t er_key;
178
179 /**
180 * Key for generating auth payload (initiator)
181 */
182 chunk_t pi_key;
183
184 /**
185 * Key for generating auth payload (responder)
186 */
187 chunk_t pr_key;
188
189 } secrets;
190
191 /**
192 * next message id to receive
193 */
194 u_int32_t message_id_in;
195
196 /**
197 * next message id to send
198 */
199 u_int32_t message_id_out;
200
201 /**
202 * a logger for this IKE_SA
203 */
204 logger_t *logger;
205 };
206
207
208 /**
209 * @brief implements function process_message of protected_ike_sa_t
210 */
211 static status_t process_message (private_ike_sa_t *this, message_t *message)
212 {
213 u_int32_t message_id;
214 exchange_type_t exchange_type;
215 bool is_request;
216 status_t status;
217
218 /* we must process each request or response from remote host */
219
220 /* find out type of message (request or response) */
221 is_request = message->get_request(message);
222 exchange_type = message->get_exchange_type(message);
223
224 this->logger->log(this->logger, CONTROL, "Process %s message of exchange type %s",(is_request) ? "REQUEST" : "RESPONSE",mapping_find(exchange_type_m,exchange_type));
225
226 message_id = message->get_message_id(message);
227
228 /*
229 * It has to be checked, if the message has to be resent cause of lost packets!
230 */
231 if (is_request && ( message_id == (this->message_id_in - 1)))
232 {
233 /* message can be resent ! */
234 this->logger->log(this->logger, CONTROL|MORE, "Resent message detected. Send stored reply");
235 return (this->resend_last_reply(this));
236 }
237
238 /* Now, the message id is checked for request AND reply */
239 if (is_request)
240 {
241 /* In a request, the message has to be this->message_id_in (other case is already handled) */
242 if (message_id != this->message_id_in)
243 {
244 this->logger->log(this->logger, ERROR | MORE, "Message request with message id %d received, but %d expected",message_id,this->message_id_in);
245 return FAILED;
246 }
247 }
248 else
249 {
250 /* In a reply, the message has to be this->message_id_out -1 cause it is the reply to the last sent message*/
251 if (message_id != (this->message_id_out - 1))
252 {
253 this->logger->log(this->logger, ERROR | MORE, "Message reply with message id %d received, but %d expected",message_id,this->message_id_in);
254 return FAILED;
255 }
256 }
257
258 /* now the message is processed by the current state object */
259 /* the current state does change the current change to the next one*/
260 status = this->current_state->process_message(this->current_state,message);
261
262 return status;
263 }
264
265 /**
266 * @brief Implements function build_message of protected_ike_sa_t.
267 */
268 static status_t build_message(private_ike_sa_t *this, exchange_type_t type, bool request, message_t **message)
269 {
270 status_t status;
271 message_t *new_message;
272 host_t *source, *destination;
273
274 this->logger->log(this->logger, CONTROL|MORE, "build empty message");
275 new_message = message_create();
276 if (new_message == NULL)
277 {
278 this->logger->log(this->logger, ERROR, "Fatal error: could not create empty message object");
279 return OUT_OF_RES;
280 }
281
282 status = this->me.host->clone(this->me.host, &source);
283 if (status != SUCCESS)
284 {
285 this->logger->log(this->logger, ERROR, "Fatal error: could not clone my host information");
286 new_message->destroy(new_message);
287 return status;
288 }
289 status = this->other.host->clone(this->other.host, &destination);
290 if (status != SUCCESS)
291 {
292 this->logger->log(this->logger, ERROR, "Fatal error: could not clone other host information");
293 source->destroy(source);
294 new_message->destroy(new_message);
295 return status;
296 }
297
298 new_message->set_source(new_message, source);
299 new_message->set_destination(new_message, destination);
300
301 new_message->set_exchange_type(new_message, type);
302 new_message->set_request(new_message, request);
303
304 new_message->set_message_id(new_message, (request) ? this->message_id_out : this->message_id_in);
305
306 status = new_message->set_ike_sa_id(new_message, this->ike_sa_id);
307 if (status != SUCCESS)
308 {
309 this->logger->log(this->logger, ERROR, "Fatal error: could not set ike_sa_id of message");
310 new_message->destroy(new_message);
311 return status;
312 }
313
314 *message = new_message;
315
316 return SUCCESS;
317 }
318
319 /**
320 * @brief implements function process_configuration of protected_ike_sa_t
321 */
322 static status_t initialize_connection(private_ike_sa_t *this, char *name)
323 {
324 /* work is done in state object of type INITIATOR_INIT */
325 initiator_init_t *current_state;
326 status_t status;
327
328 if (this->current_state->get_state(this->current_state) != INITIATOR_INIT)
329 {
330 return FAILED;
331 }
332
333 current_state = (initiator_init_t *) this->current_state;
334
335 status = current_state->initiate_connection(current_state,name);
336
337 if (status != SUCCESS)
338 {
339 this->create_delete_job(this);
340 }
341 return status;
342 }
343
344 /**
345 * @brief implements function protected_ike_sa_t.get_id
346 */
347 static ike_sa_id_t* get_id(private_ike_sa_t *this)
348 {
349 return this->ike_sa_id;
350 }
351
352 /**
353 * @brief implements function protected_ike_sa_t.compute_secrets
354 */
355 static status_t compute_secrets (private_ike_sa_t *this,chunk_t dh_shared_secret,chunk_t initiator_nonce, chunk_t responder_nonce)
356 {
357 chunk_t concatenated_nonces;
358 chunk_t skeyseed;
359 chunk_t prf_plus_seed;
360 status_t status;
361 u_int64_t initiator_spi;
362 u_int64_t responder_spi;
363 prf_plus_t *prf_plus;
364
365
366 /*
367 * TODO check length for specific prf's
368 */
369 concatenated_nonces.len = (initiator_nonce.len + responder_nonce.len);
370 concatenated_nonces.ptr = allocator_alloc(concatenated_nonces.len);
371 if (concatenated_nonces.ptr == NULL)
372 {
373 this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for concatenated nonces");
374 return FAILED;
375 }
376 /* first is initiator */
377 memcpy(concatenated_nonces.ptr,initiator_nonce.ptr,initiator_nonce.len);
378 /* second is responder */
379 memcpy(concatenated_nonces.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
380
381 this->logger->log_chunk(this->logger, RAW, "Nonce data", &concatenated_nonces);
382
383
384 /* status of set_key is not checked */
385 status = this->prf->set_key(this->prf,concatenated_nonces);
386
387 status = this->prf->allocate_bytes(this->prf,dh_shared_secret,&skeyseed);
388 if (status != SUCCESS)
389 {
390 allocator_free_chunk(&concatenated_nonces);
391 this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate bytes for skeyseed");
392 return status;
393 }
394 allocator_free_chunk(&concatenated_nonces);
395
396 prf_plus_seed.len = (initiator_nonce.len + responder_nonce.len + 16);
397 prf_plus_seed.ptr = allocator_alloc(prf_plus_seed.len);
398 if (prf_plus_seed.ptr == NULL)
399 {
400 this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for prf+ seed");
401 allocator_free_chunk(&skeyseed);
402 return FAILED;
403 }
404
405
406 /* first is initiator */
407 memcpy(prf_plus_seed.ptr,initiator_nonce.ptr,initiator_nonce.len);
408 /* second is responder */
409 memcpy(prf_plus_seed.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
410 /* third is initiator spi */
411 initiator_spi = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
412 memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len,&initiator_spi,8);
413 /* fourth is responder spi */
414 responder_spi = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
415 memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len + 8,&responder_spi,8);
416
417 this->logger->log_chunk(this->logger, PRIVATE | MORE, "Keyseed", &skeyseed);
418 this->logger->log_chunk(this->logger, PRIVATE | MORE, "PRF+ Seed", &prf_plus_seed);
419
420 this->logger->log(this->logger, CONTROL | MOST, "Set new key of prf object");
421 status = this->prf->set_key(this->prf,skeyseed);
422 allocator_free_chunk(&skeyseed);
423 if (status != SUCCESS)
424 {
425 this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for prf+ seed");
426 allocator_free_chunk(&prf_plus_seed);
427 return FAILED;
428 }
429
430 this->logger->log(this->logger, CONTROL | MOST, "Create new prf+ object");
431 prf_plus = prf_plus_create(this->prf, prf_plus_seed);
432 allocator_free_chunk(&prf_plus_seed);
433 if (prf_plus == NULL)
434 {
435 this->logger->log(this->logger, ERROR, "Fatal errror: prf+ object could not be created");
436 return FAILED;
437 }
438
439 status = prf_plus->allocate_bytes(prf_plus,this->prf->get_block_size(this->prf),&(this->secrets.d_key));
440 if (status != SUCCESS)
441 {
442 this->logger->log(this->logger, ERROR | MORE, "Could not allocate bytes from prf+ for Sk_d");
443 return status;
444 }
445 this->logger->log_chunk(this->logger, PRIVATE, "Sk_d secret", &(this->secrets.d_key));
446
447 status = prf_plus->allocate_bytes(prf_plus,this->crypter_initiator->get_block_size(this->crypter_initiator),&(this->secrets.ei_key));
448 if (status != SUCCESS)
449 {
450 this->logger->log(this->logger, ERROR | MORE, "Could not allocate bytes from prf+ for Sk_ei");
451 return status;
452 }
453 this->logger->log_chunk(this->logger, PRIVATE, "Sk_ei secret", &(this->secrets.ei_key));
454 status = this->crypter_initiator->set_key(this->crypter_initiator,this->secrets.ei_key);
455 if (status != SUCCESS)
456 {
457 this->logger->log(this->logger, ERROR | MORE, "Could not set encryption key initiator crypter");
458 return status;
459 }
460
461 status = prf_plus->allocate_bytes(prf_plus,this->crypter_responder->get_block_size(this->crypter_responder),&(this->secrets.er_key));
462 if (status != SUCCESS)
463 {
464 this->logger->log(this->logger, ERROR | MORE, "Could not allocate bytes from prf+ for Sk_er");
465 return status;
466 }
467 this->logger->log_chunk(this->logger, PRIVATE, "Sk_er secret", &(this->secrets.er_key));
468 status = this->crypter_responder->set_key(this->crypter_responder,this->secrets.er_key);
469 if (status != SUCCESS)
470 {
471 this->logger->log(this->logger, ERROR | MORE, "Could not set encryption key responder crypter");
472 return status;
473 }
474
475 status = prf_plus->allocate_bytes(prf_plus,this->signer_initiator->get_block_size(this->signer_initiator),&(this->secrets.ai_key));
476 if (status != SUCCESS)
477 {
478 this->logger->log(this->logger, ERROR | MORE, "Could not allocate bytes from prf+ for Sk_ai");
479 return status;
480 }
481 this->logger->log_chunk(this->logger, PRIVATE, "Sk_ai secret", &(this->secrets.ai_key));
482 status = this->signer_initiator->set_key(this->signer_initiator,this->secrets.ai_key);
483 if (status != SUCCESS)
484 {
485 this->logger->log(this->logger, ERROR | MORE, "Could not set key for initiator signer");
486 return status;
487 }
488
489 status = prf_plus->allocate_bytes(prf_plus,this->signer_responder->get_block_size(this->signer_responder),&(this->secrets.ar_key));
490 if (status != SUCCESS)
491 {
492 this->logger->log(this->logger, ERROR | MORE, "Could not allocate bytes from prf+ for Sk_ar");
493 return status;
494 }
495 this->logger->log_chunk(this->logger, PRIVATE, "Sk_ar secret", &(this->secrets.ar_key));
496 status = this->signer_responder->set_key(this->signer_responder,this->secrets.ar_key);
497 if (status != SUCCESS)
498 {
499 this->logger->log(this->logger, ERROR | MORE, "Could not set key for responder signer");
500 return status;
501 }
502
503 status = prf_plus->allocate_bytes(prf_plus,this->crypter_responder->get_block_size(this->crypter_responder),&(this->secrets.pi_key));
504 if (status != SUCCESS)
505 {
506 this->logger->log(this->logger, ERROR | MORE, "Could not allocate bytes from prf+ for Sk_pi");
507 return status;
508 }
509 this->logger->log_chunk(this->logger, PRIVATE, "Sk_pi secret", &(this->secrets.pi_key));
510
511 status = prf_plus->allocate_bytes(prf_plus,this->crypter_responder->get_block_size(this->crypter_responder),&(this->secrets.pr_key));
512 if (status != SUCCESS)
513 {
514 this->logger->log(this->logger, ERROR | MORE, "Could not allocate bytes from prf+ for Sk_pr");
515 return status;
516 }
517 this->logger->log_chunk(this->logger, PRIVATE, "Sk_pr secret", &(this->secrets.pr_key));
518
519 prf_plus->destroy(prf_plus);
520
521 return SUCCESS;
522 }
523
524 /**
525 * @brief implements function resend_last_reply of protected_ike_sa_t
526 */
527 status_t resend_last_reply (private_ike_sa_t *this)
528 {
529 packet_t *packet;
530 status_t status;
531
532 status = this->last_responded_message->generate(this->last_responded_message, &packet);
533 if (status != SUCCESS)
534 {
535 this->logger->log(this->logger, ERROR, "Could not generate message to resent");
536 return status;
537 }
538
539 status = global_send_queue->add(global_send_queue, packet);
540 if (status != SUCCESS)
541 {
542 this->logger->log(this->logger, ERROR, "Could not add packet to send queue");
543 packet->destroy(packet);
544 return status;
545 }
546 return SUCCESS;
547 }
548
549 status_t create_delete_job (private_ike_sa_t *this)
550 {
551 job_t *delete_job;
552 status_t status;
553
554 this->logger->log(this->logger, CONTROL | MORE, "Going to create job to delete this IKE_SA");
555
556 delete_job = (job_t *) delete_ike_sa_job_create(this->ike_sa_id);
557 if (delete_job == NULL)
558 {
559 this->logger->log(this->logger, ERROR, "Job to delete IKE SA could not be created");
560 return FAILED;
561 }
562
563 status = global_job_queue->add(global_job_queue,delete_job);
564 if (status != SUCCESS)
565 {
566 this->logger->log(this->logger, ERROR, "%s Job to delete IKE SA could not be added to job queue",mapping_find(status_m,status));
567 delete_job->destroy_all(delete_job);
568 return status;
569 }
570 return SUCCESS;
571 }
572
573 /**
574 * Implementation of protected_ike_sa_t.set_new_state.
575 */
576 static void set_new_state (private_ike_sa_t *this, state_t *state)
577 {
578 this->logger->log(this->logger, ERROR, "Change current state %s to %s",mapping_find(ike_sa_state_m,this->current_state->get_state(this->current_state)),mapping_find(ike_sa_state_m,state->get_state(state)));
579 this->current_state = state;
580 }
581
582 /**
583 * Implementation of protected_ike_sa_t.get_logger.
584 */
585 static logger_t *get_logger (private_ike_sa_t *this)
586 {
587 return this->logger;
588 }
589
590 /**
591 * Implementation of protected_ike_sa_t.get_my_host.
592 */
593 static host_t *get_my_host (private_ike_sa_t *this)
594 {
595 return this->me.host;
596 }
597
598 /**
599 * Implementation of protected_ike_sa_t.get_other_host.
600 */
601 static host_t *get_other_host (private_ike_sa_t *this)
602 {
603 return this->other.host;
604 }
605
606 /**
607 * Implementation of protected_ike_sa_t.set_my_host.
608 */
609 static void set_my_host (private_ike_sa_t *this, host_t *my_host)
610 {
611 if (this->me.host != NULL)
612 {
613 this ->logger->log(this->logger, CONTROL|MOST, "Destroy existing my host object");
614 this->me.host->destroy(this->me.host);
615 }
616 this->me.host = my_host;
617 }
618
619 /**
620 * Implementation of protected_ike_sa_t.set_other_host.
621 */
622 static void set_other_host (private_ike_sa_t *this, host_t *other_host)
623 {
624 if (this->other.host != NULL)
625 {
626 this ->logger->log(this->logger, CONTROL|MOST, "Destroy existing other host object");
627 this->other.host->destroy(this->other.host);
628 }
629 this->other.host = other_host;
630 }
631
632 /**
633 * Implementation of protected_ike_sa_t.set_prf.
634 */
635 static status_t create_transforms_from_proposal (private_ike_sa_t *this,proposal_substructure_t *proposal)
636 {
637 status_t status;
638 u_int16_t encryption_algorithm;
639 u_int16_t encryption_algorithm_key_length;
640 u_int16_t integrity_algorithm;
641 u_int16_t integrity_algorithm_key_length;
642 u_int16_t pseudo_random_function;
643 u_int16_t pseudo_random_function_key_length;
644
645 this ->logger->log(this->logger, CONTROL|MORE, "Going to create transform objects for proposal");
646
647 this ->logger->log(this->logger, CONTROL|MOST, "Get encryption transform type");
648 status = proposal->get_info_for_transform_type(proposal,ENCRYPTION_ALGORITHM,&(encryption_algorithm),&(encryption_algorithm_key_length));
649 if (status != SUCCESS)
650 {
651 this ->logger->log(this->logger, ERROR|MORE, "Could not get encryption transform type");
652 return status;
653 }
654 this ->logger->log(this->logger, CONTROL|MORE, "Encryption algorithm: %s with keylength %d",mapping_find(encryption_algorithm_m,encryption_algorithm),encryption_algorithm_key_length);
655
656 this ->logger->log(this->logger, CONTROL|MOST, "Get integrity transform type");
657 status = proposal->get_info_for_transform_type(proposal,INTEGRITY_ALGORITHM,&(integrity_algorithm),&(integrity_algorithm_key_length));
658 if (status != SUCCESS)
659 {
660 this ->logger->log(this->logger, ERROR|MORE, "Could not get integrity transform type");
661 return status;
662 }
663 this ->logger->log(this->logger, CONTROL|MORE, "integrity algorithm: %s with keylength %d",mapping_find(integrity_algorithm_m,integrity_algorithm),integrity_algorithm_key_length);
664
665 this ->logger->log(this->logger, CONTROL|MOST, "Get prf transform type");
666 status = proposal->get_info_for_transform_type(proposal,PSEUDO_RANDOM_FUNCTION,&(pseudo_random_function),&(pseudo_random_function_key_length));
667 if (status != SUCCESS)
668 {
669 this ->logger->log(this->logger, ERROR|MORE, "Could not prf transform type");
670 return status;
671 }
672 this ->logger->log(this->logger, CONTROL|MORE, "prf: %s with keylength %d",mapping_find(pseudo_random_function_m,pseudo_random_function),pseudo_random_function_key_length);
673
674
675
676
677 if (this->prf != NULL)
678 {
679 this ->logger->log(this->logger, CONTROL|MOST, "Destroy existing prf_t object");
680 this->prf->destroy(this->prf);
681 }
682 this->prf = prf_create(pseudo_random_function);
683 if (this->prf == NULL)
684 {
685 this ->logger->log(this->logger, ERROR|MORE, "prf does not seem to be supported!");
686 return FAILED;
687 }
688
689 if (this->crypter_initiator != NULL)
690 {
691 this ->logger->log(this->logger, CONTROL|MOST, "Destroy existing initiator crypter_t object");
692 this->crypter_initiator->destroy(this->crypter_initiator);
693 }
694 this->crypter_initiator = crypter_create(encryption_algorithm,encryption_algorithm_key_length);
695 if (this->crypter_initiator == NULL)
696 {
697 this ->logger->log(this->logger, ERROR|MORE, "encryption algorithm does not seem to be supported!");
698 return FAILED;
699 }
700
701 if (this->crypter_responder != NULL)
702 {
703 this ->logger->log(this->logger, CONTROL|MOST, "Destroy existing responder crypter_t object");
704 this->crypter_responder->destroy(this->crypter_responder);
705 }
706 this->crypter_responder = crypter_create(encryption_algorithm,encryption_algorithm_key_length);
707 if (this->crypter_responder == NULL)
708 {
709 this ->logger->log(this->logger, ERROR|MORE, "encryption algorithm does not seem to be supported!");
710 return FAILED;
711 }
712
713 if (this->signer_initiator != NULL)
714 {
715 this ->logger->log(this->logger, CONTROL|MOST, "Destroy existing initiator signer_t object");
716 this->signer_initiator->destroy(this->signer_initiator);
717 }
718 this->signer_initiator = signer_create(integrity_algorithm);
719 if (this->signer_initiator == NULL)
720 {
721 this ->logger->log(this->logger, ERROR|MORE, "integrity algorithm does not seem to be supported!");
722 return FAILED;
723 }
724
725
726 if (this->signer_responder != NULL)
727 {
728 this ->logger->log(this->logger, CONTROL|MOST, "Destroy existing responder signer_t object");
729 this->signer_responder->destroy(this->signer_responder);
730 }
731 this->signer_responder = signer_create(integrity_algorithm);
732 if (this->signer_responder == NULL)
733 {
734 this ->logger->log(this->logger, ERROR|MORE, "integrity algorithm does not seem to be supported!");
735 return FAILED;
736 }
737
738 return SUCCESS;
739 }
740
741 /**
742 * Implementation of protected_ike_sa_t.get_randomizer.
743 */
744 static randomizer_t *get_randomizer (private_ike_sa_t *this)
745 {
746 return this->randomizer;
747 }
748
749 /**
750 * Implementation of protected_ike_sa_t.set_last_requested_message.
751 */
752 static status_t set_last_requested_message (private_ike_sa_t *this,message_t * message)
753 {
754 if ( this->last_requested_message != NULL)
755 {
756 /* destroy message */
757 this ->logger->log(this->logger, CONTROL|MOST, "Destroy stored last requested message");
758 this->last_requested_message->destroy(this->last_requested_message);
759 }
760
761 if (message->get_message_id(message) != this->message_id_out)
762 {
763 this ->logger->log(this->logger, CONTROL|MOST, "last requested message could not be set cause id was not as expected");
764 return FAILED;
765 }
766 this ->logger->log(this->logger, CONTROL|MOST, "replace last requested message with new one");
767 this->last_requested_message = message;
768
769 /* message counter can now be increased */
770 this ->logger->log(this->logger, CONTROL|MOST, "Increate message counter for outgoing messages");
771 this->message_id_out++;
772 return SUCCESS;
773 }
774
775
776 /**
777 * Implementation of protected_ike_sa_t.set_last_responded_message.
778 */
779 static status_t set_last_responded_message (private_ike_sa_t *this,message_t * message)
780 {
781 if ( this->last_responded_message != NULL)
782 {
783 /* destroy message */
784 this ->logger->log(this->logger, CONTROL|MOST, "Destroy stored last responded message");
785 this->last_responded_message->destroy(this->last_responded_message);
786 }
787 if (message->get_message_id(message) != this->message_id_in)
788 {
789 this ->logger->log(this->logger, CONTROL|MOST, "last responded message could not be set cause id was not as expected");
790 return FAILED;
791
792 }
793 this ->logger->log(this->logger, CONTROL|MOST, "replace last responded message with new one");
794 this->last_responded_message = message;
795
796 /* message counter can now be increased */
797 this ->logger->log(this->logger, CONTROL|MOST, "Increate message counter for incoming messages");
798 this->message_id_in++;
799
800 return SUCCESS;
801 }
802
803
804 /**
805 * @brief implements function destroy of protected_ike_sa_t
806 */
807 static status_t destroy (private_ike_sa_t *this)
808 {
809
810 this->logger->log(this->logger, CONTROL | MORE, "Going to destroy IKE_SA");
811
812 /* destroy child sa's */
813 this->logger->log(this->logger, CONTROL | MOST, "Destroy all child_sa's");
814 while (this->child_sas->get_count(this->child_sas) > 0)
815 {
816 void *child_sa;
817 if (this->child_sas->remove_first(this->child_sas,&child_sa) != SUCCESS)
818 {
819 break;
820 }
821 /* destroy child sa */
822 }
823 this->child_sas->destroy(this->child_sas);
824
825 this->logger->log(this->logger, CONTROL | MOST, "Destroy secrets");
826 if (this->secrets.d_key.ptr != NULL)
827 {
828 allocator_free(this->secrets.d_key.ptr);
829 }
830 if (this->secrets.ai_key.ptr != NULL)
831 {
832 allocator_free(this->secrets.ai_key.ptr);
833 }
834 if (this->secrets.ar_key.ptr != NULL)
835 {
836 allocator_free(this->secrets.ar_key.ptr);
837 }
838 if (this->secrets.ei_key.ptr != NULL)
839 {
840 allocator_free(this->secrets.ei_key.ptr);
841 }
842 if (this->secrets.er_key.ptr != NULL)
843 {
844 allocator_free(this->secrets.er_key.ptr);
845 }
846 if (this->secrets.pi_key.ptr != NULL)
847 {
848 allocator_free(this->secrets.pi_key.ptr);
849 }
850 if (this->secrets.pr_key.ptr != NULL)
851 {
852 allocator_free(this->secrets.pr_key.ptr);
853 }
854
855 if ( this->crypter_initiator != NULL)
856 {
857 this->logger->log(this->logger, CONTROL | MOST, "Destroy initiator crypter");
858 this->crypter_initiator->destroy(this->crypter_initiator);
859 }
860
861 if ( this->crypter_responder != NULL)
862 {
863 this->logger->log(this->logger, CONTROL | MOST, "Destroy responder crypter");
864 this->crypter_responder->destroy(this->crypter_responder);
865 }
866
867 if ( this->signer_initiator != NULL)
868 {
869 this->logger->log(this->logger, CONTROL | MOST, "Destroy initiator signer");
870 this->signer_initiator->destroy(this->signer_initiator);
871 }
872
873 if (this->signer_responder != NULL)
874 {
875 this->logger->log(this->logger, CONTROL | MOST, "Destroy responder signer");
876 this->signer_responder->destroy(this->signer_responder);
877 }
878
879 if (this->prf != NULL)
880 {
881 this->logger->log(this->logger, CONTROL | MOST, "Destroy prf");
882 this->prf->destroy(this->prf);
883 }
884
885 /* destroy ike_sa_id */
886 this->logger->log(this->logger, CONTROL | MOST, "Destroy assigned ike_sa_id");
887 this->ike_sa_id->destroy(this->ike_sa_id);
888
889 /* destroy stored requested message */
890 if (this->last_requested_message != NULL)
891 {
892 this->logger->log(this->logger, CONTROL | MOST, "Destroy last requested message");
893 this->last_requested_message->destroy(this->last_requested_message);
894 }
895
896 /* destroy stored responded messages */
897 if (this->last_responded_message != NULL)
898 {
899 this->logger->log(this->logger, CONTROL | MOST, "Destroy last responded message");
900 this->last_responded_message->destroy(this->last_responded_message);
901 }
902
903 this->logger->log(this->logger, CONTROL | MOST, "Destroy randomizer");
904 this->randomizer->destroy(this->randomizer);
905
906 if (this->me.host != NULL)
907 {
908 this->logger->log(this->logger, CONTROL | MOST, "Destroy host informations of me");
909 this->me.host->destroy(this->me.host);
910 }
911
912 if (this->other.host != NULL)
913 {
914 this->logger->log(this->logger, CONTROL | MOST, "Destroy host informations of other");
915 this->other.host->destroy(this->other.host);
916 }
917
918 this->logger->log(this->logger, CONTROL | MOST, "Destroy current state object");
919 this->current_state->destroy(this->current_state);
920
921 this->logger->log(this->logger, CONTROL | MOST, "Destroy logger of IKE_SA");
922
923 global_logger_manager->destroy_logger(global_logger_manager, this->logger);
924
925 allocator_free(this);
926 return SUCCESS;
927 }
928
929 /*
930 * Described in Header
931 */
932 ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
933 {
934 private_ike_sa_t *this = allocator_alloc_thing(private_ike_sa_t);
935 if (this == NULL)
936 {
937 return NULL;
938 }
939
940 /* Public functions */
941 this->protected.public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message;
942 this->protected.public.initialize_connection = (status_t(*)(ike_sa_t*, char*)) initialize_connection;
943 this->protected.public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id;
944 this->protected.public.destroy = (status_t(*)(ike_sa_t*))destroy;
945
946 /* protected functions */
947 this->protected.build_message = (status_t (*) (protected_ike_sa_t *, exchange_type_t , bool , message_t **)) build_message;
948 this->protected.compute_secrets = (status_t (*) (protected_ike_sa_t *,chunk_t ,chunk_t , chunk_t )) compute_secrets;
949 this->protected.get_logger = (logger_t *(*) (protected_ike_sa_t *)) get_logger;
950 this->protected.get_my_host = (host_t *(*) (protected_ike_sa_t *)) get_my_host;
951 this->protected.get_other_host = (host_t *(*) (protected_ike_sa_t *)) get_other_host;
952 this->protected.set_my_host = (void(*) (protected_ike_sa_t *,host_t *)) set_my_host;
953 this->protected.set_other_host = (void(*) (protected_ike_sa_t *, host_t *)) set_other_host;
954 this->protected.get_randomizer = (randomizer_t *(*) (protected_ike_sa_t *)) get_randomizer;
955 this->protected.set_last_requested_message = (status_t (*) (protected_ike_sa_t *,message_t *)) set_last_requested_message;
956 this->protected.set_last_responded_message = (status_t (*) (protected_ike_sa_t *,message_t *)) set_last_responded_message;
957 this->protected.create_transforms_from_proposal = (status_t (*) (protected_ike_sa_t *,proposal_substructure_t *)) create_transforms_from_proposal;
958 this->protected.set_new_state = (void (*) (protected_ike_sa_t *,state_t *)) set_new_state;
959
960 /* private functions */
961 this->resend_last_reply = resend_last_reply;
962 this->create_delete_job = create_delete_job;
963
964
965 /* initialize private fields */
966 this->logger = global_logger_manager->create_logger(global_logger_manager, IKE_SA, NULL);
967 if (this->logger == NULL)
968 {
969 allocator_free(this);
970 }
971
972 if (ike_sa_id->clone(ike_sa_id,&(this->ike_sa_id)) != SUCCESS)
973 {
974 this->logger->log(this->logger, ERROR, "Fatal error: Could not clone ike_sa_id");
975 global_logger_manager->destroy_logger(global_logger_manager,this->logger);
976 allocator_free(this);
977 return NULL;
978 }
979 this->child_sas = linked_list_create();
980 if (this->child_sas == NULL)
981 {
982 this->logger->log(this->logger, ERROR, "Fatal error: Could not create list for child_sa's");
983 this->ike_sa_id->destroy(this->ike_sa_id);
984 global_logger_manager->destroy_logger(global_logger_manager,this->logger);
985 allocator_free(this);
986 return NULL;
987 }
988 this->randomizer = randomizer_create();
989 if (this->randomizer == NULL)
990 {
991 this->logger->log(this->logger, ERROR, "Fatal error: Could not create list for child_sa's");
992 this->child_sas->destroy(this->child_sas);
993 this->ike_sa_id->destroy(this->ike_sa_id);
994 global_logger_manager->destroy_logger(global_logger_manager,this->logger);
995 allocator_free(this);
996 }
997
998 this->me.host = NULL;
999 this->other.host = NULL;
1000 this->last_requested_message = NULL;
1001 this->last_responded_message = NULL;
1002 this->message_id_out = 0;
1003 this->message_id_in = 0;
1004 this->secrets.d_key.ptr = NULL;
1005 this->secrets.d_key.len = 0;
1006 this->secrets.ai_key.ptr = NULL;
1007 this->secrets.ai_key.len = 0;
1008 this->secrets.ar_key.ptr = NULL;
1009 this->secrets.ar_key.len = 0;
1010 this->secrets.ei_key.ptr = NULL;
1011 this->secrets.ei_key.len = 0;
1012 this->secrets.er_key.ptr = NULL;
1013 this->secrets.er_key.len = 0;
1014 this->secrets.pi_key.ptr = NULL;
1015 this->secrets.pi_key.len = 0;
1016 this->secrets.pr_key.ptr = NULL;
1017 this->secrets.pr_key.len = 0;
1018 this->crypter_initiator = NULL;
1019 this->crypter_responder = NULL;
1020 this->signer_initiator = NULL;
1021 this->signer_responder = NULL;
1022 this->prf = NULL;
1023
1024
1025
1026
1027 /* at creation time, IKE_SA is in a initiator state */
1028 if (ike_sa_id->is_initiator(ike_sa_id))
1029 {
1030 this->current_state = (state_t *) initiator_init_create(&(this->protected));
1031 }
1032 else
1033 {
1034 this->current_state = (state_t *) responder_init_create(&(this->protected));
1035 }
1036
1037 if (this->current_state == NULL)
1038 {
1039 this->logger->log(this->logger, ERROR, "Fatal error: Could not create state object");
1040 this->child_sas->destroy(this->child_sas);
1041 this->ike_sa_id->destroy(this->ike_sa_id);
1042 global_logger_manager->destroy_logger(global_logger_manager,this->logger);
1043 this->randomizer->destroy(this->randomizer);
1044 allocator_free(this);
1045 }
1046
1047
1048 return &(this->protected.public);
1049 }