4 * @brief Implementation of ike_sa_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
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>
48 typedef struct private_ike_sa_t private_ike_sa_t
;
51 * Private data of an ike_sa_t object.
53 struct private_ike_sa_t
{
56 * Protected part of a ike_sa_t object.
58 protected_ike_sa_t
protected;
61 * Creates a job to delete the given IKE_SA.
63 * @param this calling object
65 status_t (*create_delete_job
) (private_ike_sa_t
*this);
68 * Resends the last sent reply.
70 * @param this calling object
72 status_t (*resend_last_reply
) (private_ike_sa_t
*this);
77 * Identifier for the current IKE_SA
79 ike_sa_id_t
*ike_sa_id
;
82 * Linked List containing the child sa's of the current IKE_SA
84 linked_list_t
*child_sas
;
89 init_config_t
*init_config
;
94 sa_config_t
*sa_config
;
97 * Current state of the IKE_SA
99 state_t
*current_state
;
102 * this SA's source for random data
104 randomizer_t
*randomizer
;
107 * contains the last responded message
110 message_t
*last_responded_message
;
113 * contains the last requested message
116 message_t
*last_requested_message
;
119 * Informations of this host
126 * Informations of the other host
133 * Crypter object for initiator
135 crypter_t
*crypter_initiator
;
138 * Crypter object for responder
140 crypter_t
*crypter_responder
;
143 * Signer object for initiator
145 signer_t
*signer_initiator
;
148 * Signer object for responder
150 signer_t
*signer_responder
;
164 * Key used for deriving other keys
169 * Key for authenticate (initiator)
174 * Key for authenticate (responder)
179 * Key for encryption (initiator)
184 * Key for encryption (responder)
189 * Key for generating auth payload (initiator)
194 * Key for generating auth payload (responder)
201 * next message id to receive.
203 u_int32_t message_id_in
;
206 * next message id to send.
208 u_int32_t message_id_out
;
211 * Last message id which was successfully replied.
213 u_int32_t last_replied_message_id
;
216 * a logger for this IKE_SA
223 * Implements protected_ike_sa_t.process_message.
225 static status_t
process_message (private_ike_sa_t
*this, message_t
*message
)
227 u_int32_t message_id
;
228 exchange_type_t exchange_type
;
231 /* we must process each request or response from remote host */
233 /* find out type of message (request or response) */
234 is_request
= message
->get_request(message
);
235 exchange_type
= message
->get_exchange_type(message
);
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
));
239 message_id
= message
->get_message_id(message
);
242 * It has to be checked, if the message has to be resent cause of lost packets!
244 if (is_request
&& (message_id
== (this->message_id_in
- 1)))
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));
251 /* Now, the message id is checked for request AND reply */
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
)
257 this->logger
->log(this->logger
, ERROR
| MORE
, "Message request with message id %d received, but %d expected",message_id
,this->message_id_in
);
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))
266 this->logger
->log(this->logger
, ERROR
| MORE
, "Message reply with message id %d received, but %d expected",message_id
,this->message_id_in
);
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
);
277 * Implements protected_ike_sa_t.build_message.
279 static void build_message(private_ike_sa_t
*this, exchange_type_t type
, bool request
, message_t
**message
)
281 message_t
*new_message
;
282 host_t
*source
, *destination
;
284 this->logger
->log(this->logger
, CONTROL
|MORE
, "build empty message");
285 new_message
= message_create();
287 source
= this->me
.host
->clone(this->me
.host
);
288 destination
= this->other
.host
->clone(this->other
.host
);
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
;
300 * Implements protected_ike_sa_t.process_configuration.
302 static status_t
initialize_connection(private_ike_sa_t
*this, char *name
)
304 /* work is done in state object of type INITIATOR_INIT */
305 initiator_init_t
*current_state
;
308 if (this->current_state
->get_state(this->current_state
) != INITIATOR_INIT
)
313 current_state
= (initiator_init_t
*) this->current_state
;
315 status
= current_state
->initiate_connection(current_state
,name
);
321 * Implements protected_ike_sa_t.get_id.
323 static ike_sa_id_t
* get_id(private_ike_sa_t
*this)
325 return this->ike_sa_id
;
329 * Implements protected_ike_sa_t.compute_secrets.
331 static void compute_secrets(private_ike_sa_t
*this,chunk_t dh_shared_secret
,chunk_t initiator_nonce
, chunk_t responder_nonce
)
333 chunk_t concatenated_nonces
;
335 chunk_t prf_plus_seed
;
336 u_int64_t initiator_spi
;
337 u_int64_t responder_spi
;
338 prf_plus_t
*prf_plus
;
342 * TODO check length for specific prf's
344 concatenated_nonces
.len
= (initiator_nonce
.len
+ responder_nonce
.len
);
345 concatenated_nonces
.ptr
= allocator_alloc(concatenated_nonces
.len
);
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
);
352 this->logger
->log_chunk(this->logger
, RAW
, "Nonce data", &concatenated_nonces
);
354 /* status of set_key is not checked */
355 this->prf
->set_key(this->prf
,concatenated_nonces
);
357 this->prf
->allocate_bytes(this->prf
,dh_shared_secret
,&skeyseed
);
359 allocator_free_chunk(&concatenated_nonces
);
361 prf_plus_seed
.len
= (initiator_nonce
.len
+ responder_nonce
.len
+ 16);
362 prf_plus_seed
.ptr
= allocator_alloc(prf_plus_seed
.len
);
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);
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
);
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
);
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
);
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
));
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
);
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
);
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
);
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
);
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
));
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
));
412 prf_plus
->destroy(prf_plus
);
416 * Implementation of private_ike_sa_t.resend_last_reply.
418 static status_t
resend_last_reply(private_ike_sa_t
*this)
422 packet
= this->last_responded_message
->get_packet(this->last_responded_message
);
423 charon
->send_queue
->add(charon
->send_queue
, packet
);
429 * Implementation of ike_sa_t.retransmit_request.
431 status_t
retransmit_request (private_ike_sa_t
*this, u_int32_t message_id
)
435 if ((this->message_id_out
-1) != message_id
)
440 if (message_id
== this->last_replied_message_id
)
445 if (this->last_requested_message
== NULL
)
450 packet
= this->last_requested_message
->get_packet(this->last_requested_message
);
451 charon
->send_queue
->add(charon
->send_queue
, packet
);
458 * Implements protected_ike_sa_t.resend_last_reply.
460 static status_t
create_delete_job(private_ike_sa_t
*this)
464 this->logger
->log(this->logger
, CONTROL
| MORE
, "Going to create job to delete this IKE_SA");
466 delete_job
= (job_t
*) delete_ike_sa_job_create(this->ike_sa_id
);
467 charon
->job_queue
->add(charon
->job_queue
,delete_job
);
473 * Implementation of protected_ike_sa_t.set_new_state.
475 static void set_new_state (private_ike_sa_t
*this, state_t
*state
)
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
;
482 * Implementation of protected_ike_sa_t.get_logger.
484 static logger_t
*get_logger (private_ike_sa_t
*this)
490 * Implementation of protected_ike_sa_t.get_my_host.
492 static host_t
*get_my_host (private_ike_sa_t
*this)
494 return this->me
.host
;
498 * Implementation of protected_ike_sa_t.get_other_host.
500 static host_t
*get_other_host (private_ike_sa_t
*this)
502 return this->other
.host
;
506 * Implementation of protected_ike_sa_t.get_init_config.
508 static init_config_t
*get_init_config (private_ike_sa_t
*this)
510 return this->init_config
;
514 * Implementation of protected_ike_sa_t.set_init_config.
516 static void set_init_config (private_ike_sa_t
*this,init_config_t
* init_config
)
518 this->init_config
= init_config
;
522 * Implementation of protected_ike_sa_t.get_sa_config.
524 static sa_config_t
*get_sa_config (private_ike_sa_t
*this)
526 return this->sa_config
;
530 * Implementation of protected_ike_sa_t.set_sa_config.
532 static void set_sa_config (private_ike_sa_t
*this,sa_config_t
* sa_config
)
534 this->sa_config
= sa_config
;
538 * Implementation of protected_ike_sa_t.set_my_host.
540 static void set_my_host (private_ike_sa_t
*this, host_t
*my_host
)
542 this->me
.host
= my_host
;
546 * Implementation of protected_ike_sa_t.set_other_host.
548 static void set_other_host (private_ike_sa_t
*this, host_t
*other_host
)
550 this->other
.host
= other_host
;
554 * Implementation of protected_ike_sa_t.set_prf.
556 static status_t
create_transforms_from_proposal (private_ike_sa_t
*this,ike_proposal_t
*proposal
)
558 this->logger
->log(this->logger
, CONTROL
|MORE
, "Going to create transform objects for proposal");
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
);
564 if (this->prf
!= NULL
)
566 this->prf
->destroy(this->prf
);
568 this->prf
= prf_create(proposal
->pseudo_random_function
);
569 if (this->prf
== NULL
)
571 this->logger
->log(this->logger
, ERROR
|MORE
, "prf not supported!");
575 if (this->crypter_initiator
!= NULL
)
577 this->crypter_initiator
->destroy(this->crypter_initiator
);
579 this->crypter_initiator
= crypter_create(proposal
->encryption_algorithm
,proposal
->encryption_algorithm_key_length
);
580 if (this->crypter_initiator
== NULL
)
582 this->logger
->log(this->logger
, ERROR
|MORE
, "encryption algorithm not supported!");
586 if (this->crypter_responder
!= NULL
)
588 this->crypter_responder
->destroy(this->crypter_responder
);
590 this->crypter_responder
= crypter_create(proposal
->encryption_algorithm
,proposal
->encryption_algorithm_key_length
);
591 if (this->crypter_responder
== NULL
)
593 this->logger
->log(this->logger
, ERROR
|MORE
, "encryption algorithm not supported!");
597 if (this->signer_initiator
!= NULL
)
599 this->signer_initiator
->destroy(this->signer_initiator
);
601 this->signer_initiator
= signer_create(proposal
->integrity_algorithm
);
602 if (this->signer_initiator
== NULL
)
604 this->logger
->log(this->logger
, ERROR
|MORE
, "integrity algorithm not supported!");
608 if (this->signer_responder
!= NULL
)
610 this->signer_responder
->destroy(this->signer_responder
);
612 this->signer_responder
= signer_create(proposal
->integrity_algorithm
);
613 if (this->signer_responder
== NULL
)
615 this->logger
->log(this->logger
, ERROR
|MORE
, "integrity algorithm not supported!");
623 * Implementation of protected_ike_sa_t.get_randomizer.
625 static randomizer_t
*get_randomizer (private_ike_sa_t
*this)
627 return this->randomizer
;
631 * Implementation of protected_ike_sa_t.get_crypter_initiator.
633 static crypter_t
*get_crypter_initiator (private_ike_sa_t
*this)
635 return this->crypter_initiator
;
639 * Implementation of protected_ike_sa_t.get_signer_initiator.
641 static signer_t
*get_signer_initiator (private_ike_sa_t
*this)
643 return this->signer_initiator
;
647 * Implementation of protected_ike_sa_t.get_crypter_responder.
649 static crypter_t
*get_crypter_responder(private_ike_sa_t
*this)
651 return this->crypter_responder
;
655 * Implementation of protected_ike_sa_t.get_signer_responder.
657 static signer_t
*get_signer_responder (private_ike_sa_t
*this)
659 return this->signer_responder
;
663 * Implementation of protected_ike_sa_t.send_request.
665 static status_t
send_request (private_ike_sa_t
*this,message_t
* message
)
669 retransmit_request_job_t
*retransmit_job
;
672 if (message
->get_message_id(message
) != this->message_id_out
)
674 this->logger
->log(this->logger
, ERROR
, "Message could not be sent cause id was not as expected");
678 /* generate packet */
679 this->logger
->log(this->logger
, CONTROL
|MOST
, "Generate packet from message");
681 status
= message
->generate(message
, this->crypter_initiator
,this->signer_initiator
, &packet
);
682 if (status
!= SUCCESS
)
684 this->logger
->log(this->logger
, ERROR
, "Could not generate packet from message");
688 this->logger
->log(this->logger
, CONTROL
|MOST
, "Add packet to global send queue");
689 charon
->send_queue
->add(charon
->send_queue
, packet
);
691 if (this->last_requested_message
!= NULL
)
693 /* destroy message */
694 this->last_requested_message
->destroy(this->last_requested_message
);
697 this->logger
->log(this->logger
, CONTROL
|MOST
, "replace last requested message with new one");
698 this->last_requested_message
= message
;
700 retransmit_job
= retransmit_request_job_create(this->message_id_out
,this->ike_sa_id
);
702 status
= charon
->configuration_manager
->get_retransmit_timeout (charon
->configuration_manager
,retransmit_job
->get_retransmit_count(retransmit_job
),&timeout
);
704 if (status
!= SUCCESS
)
706 this->logger
->log(this->logger
, CONTROL
|MOST
, "No retransmit job for message created!");
707 retransmit_job
->destroy(retransmit_job
);
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
);
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
++;
722 * Implementation of protected_ike_sa_t.send_response.
724 static status_t
send_response (private_ike_sa_t
*this,message_t
* message
)
729 if (message
->get_message_id(message
) != this->message_id_in
)
731 this->logger
->log(this->logger
, CONTROL
|MOST
, "Message could not be sent cause id was not as expected");
735 status
= message
->generate(message
, this->crypter_responder
,this->signer_responder
, &packet
);
736 if (status
!= SUCCESS
)
738 this->logger
->log(this->logger
, ERROR
, "Could not generate packet from message");
742 this->logger
->log(this->logger
, CONTROL
|MOST
, "Add packet to global send queue");
743 charon
->send_queue
->add(charon
->send_queue
, packet
);
745 if (this->last_responded_message
!= NULL
)
747 /* destroy message */
748 this->last_responded_message
->destroy(this->last_responded_message
);
751 this->logger
->log(this->logger
, CONTROL
|MOST
, "replace last responded message with new one");
752 this->last_responded_message
= message
;
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
++;
762 * Implementation of protected_ike_sa_t.set_last_replied_message_id.
764 static void set_last_replied_message_id (private_ike_sa_t
*this,u_int32_t message_id
)
766 this->last_replied_message_id
= message_id
;
770 * Implementation of protected_ike_sa_t.reset_message_buffers.
772 static void reset_message_buffers (private_ike_sa_t
*this)
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
)
778 this->last_requested_message
->destroy(this->last_requested_message
);
779 this->last_requested_message
= NULL
;
782 /* destroy stored responded messages */
783 if (this->last_responded_message
!= NULL
)
785 this->last_responded_message
->destroy(this->last_responded_message
);
786 this->last_responded_message
= NULL
;
789 this->message_id_out
= 0;
790 this->message_id_in
= 0;
791 this->last_replied_message_id
= -1;
795 * Implementation of protected_ike_sa_t.destroy.
797 static void destroy (private_ike_sa_t
*this)
799 this->logger
->log(this->logger
, CONTROL
| MORE
, "Going to destroy IKE_SA");
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)
806 if (this->child_sas
->remove_first(this->child_sas
, &child_sa
) != SUCCESS
)
810 /* destroy child sa */
812 this->child_sas
->destroy(this->child_sas
);
814 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy secrets");
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
);
824 if (this->crypter_initiator
!= NULL
)
826 this->crypter_initiator
->destroy(this->crypter_initiator
);
829 if (this->crypter_responder
!= NULL
)
831 this->crypter_responder
->destroy(this->crypter_responder
);
834 if (this->signer_initiator
!= NULL
)
836 this->signer_initiator
->destroy(this->signer_initiator
);
839 if (this->signer_responder
!= NULL
)
841 this->signer_responder
->destroy(this->signer_responder
);
844 if (this->prf
!= NULL
)
846 this->prf
->destroy(this->prf
);
849 /* destroy ike_sa_id */
850 this->ike_sa_id
->destroy(this->ike_sa_id
);
852 /* destroy stored requested message */
853 if (this->last_requested_message
!= NULL
)
855 this->last_requested_message
->destroy(this->last_requested_message
);
858 /* destroy stored host_t objects */
859 if (this->me
.host
!= NULL
)
861 this->me
.host
->destroy(this->me
.host
);
864 /* destroy stored host_t objects */
865 if (this->other
.host
!= NULL
)
867 this->other
.host
->destroy(this->other
.host
);
871 /* destroy stored responded messages */
872 if (this->last_responded_message
!= NULL
)
874 this->last_responded_message
->destroy(this->last_responded_message
);
877 this->randomizer
->destroy(this->randomizer
);
879 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy current state object");
880 this->current_state
->destroy(this->current_state
);
882 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy logger of IKE_SA");
883 charon
->logger_manager
->destroy_logger(charon
->logger_manager
, this->logger
);
885 allocator_free(this);
889 * Described in Header
891 ike_sa_t
* ike_sa_create(ike_sa_id_t
*ike_sa_id
)
893 private_ike_sa_t
*this = allocator_alloc_thing(private_ike_sa_t
);
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
;
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
;
926 /* private functions */
927 this->resend_last_reply
= resend_last_reply
;
928 this->create_delete_job
= create_delete_job
;
930 /* initialize private fields */
931 this->logger
= charon
->logger_manager
->create_logger(charon
->logger_manager
, IKE_SA
, NULL
);
933 this->ike_sa_id
= ike_sa_id
->clone(ike_sa_id
);
934 this->child_sas
= linked_list_create();
935 this->randomizer
= randomizer_create();
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
;
956 this->init_config
= NULL
;
957 this->sa_config
= NULL
;
959 /* at creation time, IKE_SA is in a initiator state */
960 if (ike_sa_id
->is_initiator(ike_sa_id
))
962 this->current_state
= (state_t
*) initiator_init_create(&(this->protected));
966 this->current_state
= (state_t
*) responder_init_create(&(this->protected));
968 return &(this->protected.public);