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
10 * Copyright (C) 2005 Jan Hutter, Martin Willi
11 * Hochschule fuer Technik Rapperswil
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>.
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
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>
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;
62 * Creates a job to delete the given IKE_SA.
64 * @param this calling object
66 status_t (*create_delete_job
) (private_ike_sa_t
*this);
69 * Resends the last sent reply.
71 * @param this calling object
73 status_t (*resend_last_reply
) (private_ike_sa_t
*this);
78 * Identifier for the current IKE_SA
80 ike_sa_id_t
*ike_sa_id
;
83 * Linked List containing the child sa's of the current IKE_SA
85 linked_list_t
*child_sas
;
88 * Current state of the IKE_SA
90 state_t
*current_state
;
93 * this SA's source for random data
95 randomizer_t
*randomizer
;
98 * contains the last responded message
101 message_t
*last_responded_message
;
104 * contains the last requested message
107 message_t
*last_requested_message
;
110 * Informations of this host
117 * Informations of the other host
124 * Crypter object for initiator
126 crypter_t
*crypter_initiator
;
129 * Crypter object for responder
131 crypter_t
*crypter_responder
;
134 * Signer object for initiator
136 signer_t
*signer_initiator
;
139 * Signer object for responder
141 signer_t
*signer_responder
;
155 * Key used for deriving other keys
160 * Key for authenticate (initiator)
165 * Key for authenticate (responder)
170 * Key for encryption (initiator)
175 * Key for encryption (responder)
180 * Key for generating auth payload (initiator)
185 * Key for generating auth payload (responder)
192 * next message id to receive
194 u_int32_t message_id_in
;
197 * next message id to send
199 u_int32_t message_id_out
;
202 * a logger for this IKE_SA
209 * @brief implements function process_message of protected_ike_sa_t
211 static status_t
process_message (private_ike_sa_t
*this, message_t
*message
)
213 u_int32_t message_id
;
214 exchange_type_t exchange_type
;
218 /* we must process each request or response from remote host */
220 /* find out type of message (request or response) */
221 is_request
= message
->get_request(message
);
222 exchange_type
= message
->get_exchange_type(message
);
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
));
226 message_id
= message
->get_message_id(message
);
229 * It has to be checked, if the message has to be resent cause of lost packets!
231 if (is_request
&& ( message_id
== (this->message_id_in
- 1)))
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));
238 /* Now, the message id is checked for request AND reply */
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
)
244 this->logger
->log(this->logger
, ERROR
| MORE
, "Message request with message id %d received, but %d expected",message_id
,this->message_id_in
);
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))
253 this->logger
->log(this->logger
, ERROR
| MORE
, "Message reply with message id %d received, but %d expected",message_id
,this->message_id_in
);
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
);
266 * @brief Implements function build_message of protected_ike_sa_t.
268 static status_t
build_message(private_ike_sa_t
*this, exchange_type_t type
, bool request
, message_t
**message
)
271 message_t
*new_message
;
272 host_t
*source
, *destination
;
274 this->logger
->log(this->logger
, CONTROL
|MORE
, "build empty message");
275 new_message
= message_create();
276 if (new_message
== NULL
)
278 this->logger
->log(this->logger
, ERROR
, "Fatal error: could not create empty message object");
282 status
= this->me
.host
->clone(this->me
.host
, &source
);
283 if (status
!= SUCCESS
)
285 this->logger
->log(this->logger
, ERROR
, "Fatal error: could not clone my host information");
286 new_message
->destroy(new_message
);
289 status
= this->other
.host
->clone(this->other
.host
, &destination
);
290 if (status
!= SUCCESS
)
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
);
298 new_message
->set_source(new_message
, source
);
299 new_message
->set_destination(new_message
, destination
);
301 new_message
->set_exchange_type(new_message
, type
);
302 new_message
->set_request(new_message
, request
);
304 new_message
->set_message_id(new_message
, (request
) ?
this->message_id_out
: this->message_id_in
);
306 new_message
->set_ike_sa_id(new_message
, this->ike_sa_id
);
308 *message
= new_message
;
314 * @brief implements function process_configuration of protected_ike_sa_t
316 static status_t
initialize_connection(private_ike_sa_t
*this, char *name
)
318 /* work is done in state object of type INITIATOR_INIT */
319 initiator_init_t
*current_state
;
322 if (this->current_state
->get_state(this->current_state
) != INITIATOR_INIT
)
327 current_state
= (initiator_init_t
*) this->current_state
;
329 status
= current_state
->initiate_connection(current_state
,name
);
331 if (status
!= SUCCESS
)
333 this->create_delete_job(this);
339 * @brief implements function protected_ike_sa_t.get_id
341 static ike_sa_id_t
* get_id(private_ike_sa_t
*this)
343 return this->ike_sa_id
;
347 * @brief implements function protected_ike_sa_t.compute_secrets
349 static status_t
compute_secrets (private_ike_sa_t
*this,chunk_t dh_shared_secret
,chunk_t initiator_nonce
, chunk_t responder_nonce
)
351 chunk_t concatenated_nonces
;
353 chunk_t prf_plus_seed
;
355 u_int64_t initiator_spi
;
356 u_int64_t responder_spi
;
357 prf_plus_t
*prf_plus
;
361 * TODO check length for specific prf's
363 concatenated_nonces
.len
= (initiator_nonce
.len
+ responder_nonce
.len
);
364 concatenated_nonces
.ptr
= allocator_alloc(concatenated_nonces
.len
);
365 if (concatenated_nonces
.ptr
== NULL
)
367 this->logger
->log(this->logger
, ERROR
, "Fatal errror: Could not allocate memory for concatenated nonces");
370 /* first is initiator */
371 memcpy(concatenated_nonces
.ptr
,initiator_nonce
.ptr
,initiator_nonce
.len
);
372 /* second is responder */
373 memcpy(concatenated_nonces
.ptr
+ initiator_nonce
.len
,responder_nonce
.ptr
,responder_nonce
.len
);
375 this->logger
->log_chunk(this->logger
, RAW
, "Nonce data", &concatenated_nonces
);
378 /* status of set_key is not checked */
379 status
= this->prf
->set_key(this->prf
,concatenated_nonces
);
381 status
= this->prf
->allocate_bytes(this->prf
,dh_shared_secret
,&skeyseed
);
382 if (status
!= SUCCESS
)
384 allocator_free_chunk(&concatenated_nonces
);
385 this->logger
->log(this->logger
, ERROR
, "Fatal errror: Could not allocate bytes for skeyseed");
388 allocator_free_chunk(&concatenated_nonces
);
390 prf_plus_seed
.len
= (initiator_nonce
.len
+ responder_nonce
.len
+ 16);
391 prf_plus_seed
.ptr
= allocator_alloc(prf_plus_seed
.len
);
392 if (prf_plus_seed
.ptr
== NULL
)
394 this->logger
->log(this->logger
, ERROR
, "Fatal errror: Could not allocate memory for prf+ seed");
395 allocator_free_chunk(&skeyseed
);
400 /* first is initiator */
401 memcpy(prf_plus_seed
.ptr
,initiator_nonce
.ptr
,initiator_nonce
.len
);
402 /* second is responder */
403 memcpy(prf_plus_seed
.ptr
+ initiator_nonce
.len
,responder_nonce
.ptr
,responder_nonce
.len
);
404 /* third is initiator spi */
405 initiator_spi
= this->ike_sa_id
->get_initiator_spi(this->ike_sa_id
);
406 memcpy(prf_plus_seed
.ptr
+ initiator_nonce
.len
+ responder_nonce
.len
,&initiator_spi
,8);
407 /* fourth is responder spi */
408 responder_spi
= this->ike_sa_id
->get_responder_spi(this->ike_sa_id
);
409 memcpy(prf_plus_seed
.ptr
+ initiator_nonce
.len
+ responder_nonce
.len
+ 8,&responder_spi
,8);
411 this->logger
->log_chunk(this->logger
, PRIVATE
| MORE
, "Keyseed", &skeyseed
);
412 this->logger
->log_chunk(this->logger
, PRIVATE
| MORE
, "PRF+ Seed", &prf_plus_seed
);
414 this->logger
->log(this->logger
, CONTROL
| MOST
, "Set new key of prf object");
415 status
= this->prf
->set_key(this->prf
,skeyseed
);
416 allocator_free_chunk(&skeyseed
);
417 if (status
!= SUCCESS
)
419 this->logger
->log(this->logger
, ERROR
, "Fatal errror: Could not allocate memory for prf+ seed");
420 allocator_free_chunk(&prf_plus_seed
);
424 this->logger
->log(this->logger
, CONTROL
| MOST
, "Create new prf+ object");
425 prf_plus
= prf_plus_create(this->prf
, prf_plus_seed
);
426 allocator_free_chunk(&prf_plus_seed
);
427 if (prf_plus
== NULL
)
429 this->logger
->log(this->logger
, ERROR
, "Fatal errror: prf+ object could not be created");
433 status
= prf_plus
->allocate_bytes(prf_plus
,this->prf
->get_block_size(this->prf
),&(this->secrets
.d_key
));
434 if (status
!= SUCCESS
)
436 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not allocate bytes from prf+ for Sk_d");
439 this->logger
->log_chunk(this->logger
, PRIVATE
, "Sk_d secret", &(this->secrets
.d_key
));
441 status
= prf_plus
->allocate_bytes(prf_plus
,this->crypter_initiator
->get_block_size(this->crypter_initiator
),&(this->secrets
.ei_key
));
442 if (status
!= SUCCESS
)
444 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not allocate bytes from prf+ for Sk_ei");
447 this->logger
->log_chunk(this->logger
, PRIVATE
, "Sk_ei secret", &(this->secrets
.ei_key
));
448 status
= this->crypter_initiator
->set_key(this->crypter_initiator
,this->secrets
.ei_key
);
449 if (status
!= SUCCESS
)
451 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not set encryption key initiator crypter");
455 status
= prf_plus
->allocate_bytes(prf_plus
,this->crypter_responder
->get_block_size(this->crypter_responder
),&(this->secrets
.er_key
));
456 if (status
!= SUCCESS
)
458 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not allocate bytes from prf+ for Sk_er");
461 this->logger
->log_chunk(this->logger
, PRIVATE
, "Sk_er secret", &(this->secrets
.er_key
));
462 status
= this->crypter_responder
->set_key(this->crypter_responder
,this->secrets
.er_key
);
463 if (status
!= SUCCESS
)
465 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not set encryption key responder crypter");
469 status
= prf_plus
->allocate_bytes(prf_plus
,this->signer_initiator
->get_block_size(this->signer_initiator
),&(this->secrets
.ai_key
));
470 if (status
!= SUCCESS
)
472 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not allocate bytes from prf+ for Sk_ai");
475 this->logger
->log_chunk(this->logger
, PRIVATE
, "Sk_ai secret", &(this->secrets
.ai_key
));
476 status
= this->signer_initiator
->set_key(this->signer_initiator
,this->secrets
.ai_key
);
477 if (status
!= SUCCESS
)
479 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not set key for initiator signer");
483 status
= prf_plus
->allocate_bytes(prf_plus
,this->signer_responder
->get_block_size(this->signer_responder
),&(this->secrets
.ar_key
));
484 if (status
!= SUCCESS
)
486 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not allocate bytes from prf+ for Sk_ar");
489 this->logger
->log_chunk(this->logger
, PRIVATE
, "Sk_ar secret", &(this->secrets
.ar_key
));
490 status
= this->signer_responder
->set_key(this->signer_responder
,this->secrets
.ar_key
);
491 if (status
!= SUCCESS
)
493 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not set key for responder signer");
497 status
= prf_plus
->allocate_bytes(prf_plus
,this->crypter_responder
->get_block_size(this->crypter_responder
),&(this->secrets
.pi_key
));
498 if (status
!= SUCCESS
)
500 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not allocate bytes from prf+ for Sk_pi");
503 this->logger
->log_chunk(this->logger
, PRIVATE
, "Sk_pi secret", &(this->secrets
.pi_key
));
505 status
= prf_plus
->allocate_bytes(prf_plus
,this->crypter_responder
->get_block_size(this->crypter_responder
),&(this->secrets
.pr_key
));
506 if (status
!= SUCCESS
)
508 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not allocate bytes from prf+ for Sk_pr");
511 this->logger
->log_chunk(this->logger
, PRIVATE
, "Sk_pr secret", &(this->secrets
.pr_key
));
513 prf_plus
->destroy(prf_plus
);
519 * @brief implements function resend_last_reply of protected_ike_sa_t
521 status_t
resend_last_reply (private_ike_sa_t
*this)
526 status
= this->last_responded_message
->generate(this->last_responded_message
, NULL
, NULL
, &packet
);
527 if (status
!= SUCCESS
)
529 this->logger
->log(this->logger
, ERROR
, "Could not generate message to resent");
533 status
= global_send_queue
->add(global_send_queue
, packet
);
534 if (status
!= SUCCESS
)
536 this->logger
->log(this->logger
, ERROR
, "Could not add packet to send queue");
537 packet
->destroy(packet
);
543 status_t
create_delete_job (private_ike_sa_t
*this)
548 this->logger
->log(this->logger
, CONTROL
| MORE
, "Going to create job to delete this IKE_SA");
550 delete_job
= (job_t
*) delete_ike_sa_job_create(this->ike_sa_id
);
551 if (delete_job
== NULL
)
553 this->logger
->log(this->logger
, ERROR
, "Job to delete IKE SA could not be created");
557 status
= global_job_queue
->add(global_job_queue
,delete_job
);
558 if (status
!= SUCCESS
)
560 this->logger
->log(this->logger
, ERROR
, "%s Job to delete IKE SA could not be added to job queue",mapping_find(status_m
,status
));
561 delete_job
->destroy_all(delete_job
);
568 * Implementation of protected_ike_sa_t.set_new_state.
570 static void set_new_state (private_ike_sa_t
*this, state_t
*state
)
572 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
)));
573 this->current_state
= state
;
577 * Implementation of protected_ike_sa_t.get_logger.
579 static logger_t
*get_logger (private_ike_sa_t
*this)
585 * Implementation of protected_ike_sa_t.get_my_host.
587 static host_t
*get_my_host (private_ike_sa_t
*this)
589 return this->me
.host
;
593 * Implementation of protected_ike_sa_t.get_other_host.
595 static host_t
*get_other_host (private_ike_sa_t
*this)
597 return this->other
.host
;
601 * Implementation of protected_ike_sa_t.set_my_host.
603 static void set_my_host (private_ike_sa_t
*this, host_t
*my_host
)
605 if (this->me
.host
!= NULL
)
607 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Destroy existing my host object");
608 this->me
.host
->destroy(this->me
.host
);
610 this->me
.host
= my_host
;
614 * Implementation of protected_ike_sa_t.set_other_host.
616 static void set_other_host (private_ike_sa_t
*this, host_t
*other_host
)
618 if (this->other
.host
!= NULL
)
620 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Destroy existing other host object");
621 this->other
.host
->destroy(this->other
.host
);
623 this->other
.host
= other_host
;
627 * Implementation of protected_ike_sa_t.set_prf.
629 static status_t
create_transforms_from_proposal (private_ike_sa_t
*this,proposal_substructure_t
*proposal
)
632 u_int16_t encryption_algorithm
;
633 u_int16_t encryption_algorithm_key_length
;
634 u_int16_t integrity_algorithm
;
635 u_int16_t integrity_algorithm_key_length
;
636 u_int16_t pseudo_random_function
;
637 u_int16_t pseudo_random_function_key_length
;
639 this ->logger
->log(this->logger
, CONTROL
|MORE
, "Going to create transform objects for proposal");
641 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Get encryption transform type");
642 status
= proposal
->get_info_for_transform_type(proposal
,ENCRYPTION_ALGORITHM
,&(encryption_algorithm
),&(encryption_algorithm_key_length
));
643 if (status
!= SUCCESS
)
645 this ->logger
->log(this->logger
, ERROR
|MORE
, "Could not get encryption transform type");
648 this ->logger
->log(this->logger
, CONTROL
|MORE
, "Encryption algorithm: %s with keylength %d",mapping_find(encryption_algorithm_m
,encryption_algorithm
),encryption_algorithm_key_length
);
650 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Get integrity transform type");
651 status
= proposal
->get_info_for_transform_type(proposal
,INTEGRITY_ALGORITHM
,&(integrity_algorithm
),&(integrity_algorithm_key_length
));
652 if (status
!= SUCCESS
)
654 this ->logger
->log(this->logger
, ERROR
|MORE
, "Could not get integrity transform type");
657 this ->logger
->log(this->logger
, CONTROL
|MORE
, "integrity algorithm: %s with keylength %d",mapping_find(integrity_algorithm_m
,integrity_algorithm
),integrity_algorithm_key_length
);
659 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Get prf transform type");
660 status
= proposal
->get_info_for_transform_type(proposal
,PSEUDO_RANDOM_FUNCTION
,&(pseudo_random_function
),&(pseudo_random_function_key_length
));
661 if (status
!= SUCCESS
)
663 this ->logger
->log(this->logger
, ERROR
|MORE
, "Could not prf transform type");
666 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
);
671 if (this->prf
!= NULL
)
673 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Destroy existing prf_t object");
674 this->prf
->destroy(this->prf
);
676 this->prf
= prf_create(pseudo_random_function
);
677 if (this->prf
== NULL
)
679 this ->logger
->log(this->logger
, ERROR
|MORE
, "prf does not seem to be supported!");
683 if (this->crypter_initiator
!= NULL
)
685 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Destroy existing initiator crypter_t object");
686 this->crypter_initiator
->destroy(this->crypter_initiator
);
688 this->crypter_initiator
= crypter_create(encryption_algorithm
,encryption_algorithm_key_length
);
689 if (this->crypter_initiator
== NULL
)
691 this ->logger
->log(this->logger
, ERROR
|MORE
, "encryption algorithm does not seem to be supported!");
695 if (this->crypter_responder
!= NULL
)
697 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Destroy existing responder crypter_t object");
698 this->crypter_responder
->destroy(this->crypter_responder
);
700 this->crypter_responder
= crypter_create(encryption_algorithm
,encryption_algorithm_key_length
);
701 if (this->crypter_responder
== NULL
)
703 this ->logger
->log(this->logger
, ERROR
|MORE
, "encryption algorithm does not seem to be supported!");
707 if (this->signer_initiator
!= NULL
)
709 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Destroy existing initiator signer_t object");
710 this->signer_initiator
->destroy(this->signer_initiator
);
712 this->signer_initiator
= signer_create(integrity_algorithm
);
713 if (this->signer_initiator
== NULL
)
715 this ->logger
->log(this->logger
, ERROR
|MORE
, "integrity algorithm does not seem to be supported!");
720 if (this->signer_responder
!= NULL
)
722 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Destroy existing responder signer_t object");
723 this->signer_responder
->destroy(this->signer_responder
);
725 this->signer_responder
= signer_create(integrity_algorithm
);
726 if (this->signer_responder
== NULL
)
728 this ->logger
->log(this->logger
, ERROR
|MORE
, "integrity algorithm does not seem to be supported!");
736 * Implementation of protected_ike_sa_t.get_randomizer.
738 static randomizer_t
*get_randomizer (private_ike_sa_t
*this)
740 return this->randomizer
;
744 * Implementation of protected_ike_sa_t.set_last_requested_message.
746 static status_t
set_last_requested_message (private_ike_sa_t
*this,message_t
* message
)
748 if ( this->last_requested_message
!= NULL
)
750 /* destroy message */
751 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Destroy stored last requested message");
752 this->last_requested_message
->destroy(this->last_requested_message
);
755 if (message
->get_message_id(message
) != this->message_id_out
)
757 this ->logger
->log(this->logger
, CONTROL
|MOST
, "last requested message could not be set cause id was not as expected");
760 this ->logger
->log(this->logger
, CONTROL
|MOST
, "replace last requested message with new one");
761 this->last_requested_message
= message
;
763 /* message counter can now be increased */
764 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Increate message counter for outgoing messages");
765 this->message_id_out
++;
771 * Implementation of protected_ike_sa_t.set_last_responded_message.
773 static status_t
set_last_responded_message (private_ike_sa_t
*this,message_t
* message
)
775 if ( this->last_responded_message
!= NULL
)
777 /* destroy message */
778 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Destroy stored last responded message");
779 this->last_responded_message
->destroy(this->last_responded_message
);
781 if (message
->get_message_id(message
) != this->message_id_in
)
783 this ->logger
->log(this->logger
, CONTROL
|MOST
, "last responded message could not be set cause id was not as expected");
787 this ->logger
->log(this->logger
, CONTROL
|MOST
, "replace last responded message with new one");
788 this->last_responded_message
= message
;
790 /* message counter can now be increased */
791 this ->logger
->log(this->logger
, CONTROL
|MOST
, "Increate message counter for incoming messages");
792 this->message_id_in
++;
799 * @brief implements function destroy of protected_ike_sa_t
801 static status_t
destroy (private_ike_sa_t
*this)
804 this->logger
->log(this->logger
, CONTROL
| MORE
, "Going to destroy IKE_SA");
806 /* destroy child sa's */
807 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy all child_sa's");
808 while (this->child_sas
->get_count(this->child_sas
) > 0)
811 if (this->child_sas
->remove_first(this->child_sas
,&child_sa
) != SUCCESS
)
815 /* destroy child sa */
817 this->child_sas
->destroy(this->child_sas
);
819 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy secrets");
820 if (this->secrets
.d_key
.ptr
!= NULL
)
822 allocator_free(this->secrets
.d_key
.ptr
);
824 if (this->secrets
.ai_key
.ptr
!= NULL
)
826 allocator_free(this->secrets
.ai_key
.ptr
);
828 if (this->secrets
.ar_key
.ptr
!= NULL
)
830 allocator_free(this->secrets
.ar_key
.ptr
);
832 if (this->secrets
.ei_key
.ptr
!= NULL
)
834 allocator_free(this->secrets
.ei_key
.ptr
);
836 if (this->secrets
.er_key
.ptr
!= NULL
)
838 allocator_free(this->secrets
.er_key
.ptr
);
840 if (this->secrets
.pi_key
.ptr
!= NULL
)
842 allocator_free(this->secrets
.pi_key
.ptr
);
844 if (this->secrets
.pr_key
.ptr
!= NULL
)
846 allocator_free(this->secrets
.pr_key
.ptr
);
849 if ( this->crypter_initiator
!= NULL
)
851 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy initiator crypter");
852 this->crypter_initiator
->destroy(this->crypter_initiator
);
855 if ( this->crypter_responder
!= NULL
)
857 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy responder crypter");
858 this->crypter_responder
->destroy(this->crypter_responder
);
861 if ( this->signer_initiator
!= NULL
)
863 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy initiator signer");
864 this->signer_initiator
->destroy(this->signer_initiator
);
867 if (this->signer_responder
!= NULL
)
869 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy responder signer");
870 this->signer_responder
->destroy(this->signer_responder
);
873 if (this->prf
!= NULL
)
875 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy prf");
876 this->prf
->destroy(this->prf
);
879 /* destroy ike_sa_id */
880 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy assigned ike_sa_id");
881 this->ike_sa_id
->destroy(this->ike_sa_id
);
883 /* destroy stored requested message */
884 if (this->last_requested_message
!= NULL
)
886 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy last requested message");
887 this->last_requested_message
->destroy(this->last_requested_message
);
890 /* destroy stored responded messages */
891 if (this->last_responded_message
!= NULL
)
893 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy last responded message");
894 this->last_responded_message
->destroy(this->last_responded_message
);
897 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy randomizer");
898 this->randomizer
->destroy(this->randomizer
);
900 if (this->me
.host
!= NULL
)
902 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy host informations of me");
903 this->me
.host
->destroy(this->me
.host
);
906 if (this->other
.host
!= NULL
)
908 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy host informations of other");
909 this->other
.host
->destroy(this->other
.host
);
912 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy current state object");
913 this->current_state
->destroy(this->current_state
);
915 this->logger
->log(this->logger
, CONTROL
| MOST
, "Destroy logger of IKE_SA");
917 global_logger_manager
->destroy_logger(global_logger_manager
, this->logger
);
919 allocator_free(this);
924 * Described in Header
926 ike_sa_t
* ike_sa_create(ike_sa_id_t
*ike_sa_id
)
928 private_ike_sa_t
*this = allocator_alloc_thing(private_ike_sa_t
);
934 /* Public functions */
935 this->protected.public.process_message
= (status_t(*)(ike_sa_t
*, message_t
*)) process_message
;
936 this->protected.public.initialize_connection
= (status_t(*)(ike_sa_t
*, char*)) initialize_connection
;
937 this->protected.public.get_id
= (ike_sa_id_t
*(*)(ike_sa_t
*)) get_id
;
938 this->protected.public.destroy
= (status_t(*)(ike_sa_t
*))destroy
;
940 /* protected functions */
941 this->protected.build_message
= (status_t (*) (protected_ike_sa_t
*, exchange_type_t
, bool , message_t
**)) build_message
;
942 this->protected.compute_secrets
= (status_t (*) (protected_ike_sa_t
*,chunk_t
,chunk_t
, chunk_t
)) compute_secrets
;
943 this->protected.get_logger
= (logger_t
*(*) (protected_ike_sa_t
*)) get_logger
;
944 this->protected.get_my_host
= (host_t
*(*) (protected_ike_sa_t
*)) get_my_host
;
945 this->protected.get_other_host
= (host_t
*(*) (protected_ike_sa_t
*)) get_other_host
;
946 this->protected.set_my_host
= (void(*) (protected_ike_sa_t
*,host_t
*)) set_my_host
;
947 this->protected.set_other_host
= (void(*) (protected_ike_sa_t
*, host_t
*)) set_other_host
;
948 this->protected.get_randomizer
= (randomizer_t
*(*) (protected_ike_sa_t
*)) get_randomizer
;
949 this->protected.set_last_requested_message
= (status_t (*) (protected_ike_sa_t
*,message_t
*)) set_last_requested_message
;
950 this->protected.set_last_responded_message
= (status_t (*) (protected_ike_sa_t
*,message_t
*)) set_last_responded_message
;
951 this->protected.create_transforms_from_proposal
= (status_t (*) (protected_ike_sa_t
*,proposal_substructure_t
*)) create_transforms_from_proposal
;
952 this->protected.set_new_state
= (void (*) (protected_ike_sa_t
*,state_t
*)) set_new_state
;
954 /* private functions */
955 this->resend_last_reply
= resend_last_reply
;
956 this->create_delete_job
= create_delete_job
;
959 /* initialize private fields */
960 this->logger
= global_logger_manager
->create_logger(global_logger_manager
, IKE_SA
, NULL
);
961 if (this->logger
== NULL
)
963 allocator_free(this);
966 if (ike_sa_id
->clone(ike_sa_id
,&(this->ike_sa_id
)) != SUCCESS
)
968 this->logger
->log(this->logger
, ERROR
, "Fatal error: Could not clone ike_sa_id");
969 global_logger_manager
->destroy_logger(global_logger_manager
,this->logger
);
970 allocator_free(this);
973 this->child_sas
= linked_list_create();
974 if (this->child_sas
== NULL
)
976 this->logger
->log(this->logger
, ERROR
, "Fatal error: Could not create list for child_sa's");
977 this->ike_sa_id
->destroy(this->ike_sa_id
);
978 global_logger_manager
->destroy_logger(global_logger_manager
,this->logger
);
979 allocator_free(this);
982 this->randomizer
= randomizer_create();
983 if (this->randomizer
== NULL
)
985 this->logger
->log(this->logger
, ERROR
, "Fatal error: Could not create list for child_sa's");
986 this->child_sas
->destroy(this->child_sas
);
987 this->ike_sa_id
->destroy(this->ike_sa_id
);
988 global_logger_manager
->destroy_logger(global_logger_manager
,this->logger
);
989 allocator_free(this);
992 this->me
.host
= NULL
;
993 this->other
.host
= NULL
;
994 this->last_requested_message
= NULL
;
995 this->last_responded_message
= NULL
;
996 this->message_id_out
= 0;
997 this->message_id_in
= 0;
998 this->secrets
.d_key
.ptr
= NULL
;
999 this->secrets
.d_key
.len
= 0;
1000 this->secrets
.ai_key
.ptr
= NULL
;
1001 this->secrets
.ai_key
.len
= 0;
1002 this->secrets
.ar_key
.ptr
= NULL
;
1003 this->secrets
.ar_key
.len
= 0;
1004 this->secrets
.ei_key
.ptr
= NULL
;
1005 this->secrets
.ei_key
.len
= 0;
1006 this->secrets
.er_key
.ptr
= NULL
;
1007 this->secrets
.er_key
.len
= 0;
1008 this->secrets
.pi_key
.ptr
= NULL
;
1009 this->secrets
.pi_key
.len
= 0;
1010 this->secrets
.pr_key
.ptr
= NULL
;
1011 this->secrets
.pr_key
.len
= 0;
1012 this->crypter_initiator
= NULL
;
1013 this->crypter_responder
= NULL
;
1014 this->signer_initiator
= NULL
;
1015 this->signer_responder
= NULL
;
1021 /* at creation time, IKE_SA is in a initiator state */
1022 if (ike_sa_id
->is_initiator(ike_sa_id
))
1024 this->current_state
= (state_t
*) initiator_init_create(&(this->protected));
1028 this->current_state
= (state_t
*) responder_init_create(&(this->protected));
1031 if (this->current_state
== NULL
)
1033 this->logger
->log(this->logger
, ERROR
, "Fatal error: Could not create state object");
1034 this->child_sas
->destroy(this->child_sas
);
1035 this->ike_sa_id
->destroy(this->ike_sa_id
);
1036 global_logger_manager
->destroy_logger(global_logger_manager
,this->logger
);
1037 this->randomizer
->destroy(this->randomizer
);
1038 allocator_free(this);
1042 return &(this->protected.public);