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