- changed interface of ike_sa
[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 <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
44
45
46
47 typedef struct private_ike_sa_t private_ike_sa_t;
48
49 /**
50 * Private data of an ike_sa_t object.
51 */
52 struct private_ike_sa_t {
53
54 /**
55 * Protected part of a ike_sa_t object.
56 */
57 protected_ike_sa_t protected;
58
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 * Current state of the IKE_SA
88 */
89 state_t *current_state;
90
91 /**
92 * this SA's source for random data
93 */
94 randomizer_t *randomizer;
95
96 /**
97 * contains the last responded message
98 *
99 */
100 message_t *last_responded_message;
101
102 /**
103 * contains the last requested message
104 *
105 */
106 message_t *last_requested_message;
107
108 /**
109 * Informations of this host
110 */
111 struct {
112 host_t *host;
113 } me;
114
115 /**
116 * Informations of the other host
117 */
118 struct {
119 host_t *host;
120 } other;
121
122 /**
123 * Crypter object for initiator
124 */
125 crypter_t *crypter_initiator;
126
127 /**
128 * Crypter object for responder
129 */
130 crypter_t *crypter_responder;
131
132 /**
133 * Signer object for initiator
134 */
135 signer_t *signer_initiator;
136
137 /**
138 * Signer object for responder
139 */
140 signer_t *signer_responder;
141
142 /**
143 * prf function
144 */
145 prf_t *prf;
146
147
148
149 /**
150 * Shared secrets
151 */
152 struct {
153 /**
154 * Key used for deriving other keys
155 */
156 chunk_t d_key;
157
158 /**
159 * Key for authenticate (initiator)
160 */
161 chunk_t ai_key;
162
163 /**
164 * Key for authenticate (responder)
165 */
166 chunk_t ar_key;
167
168 /**
169 * Key for encryption (initiator)
170 */
171 chunk_t ei_key;
172
173 /**
174 * Key for encryption (responder)
175 */
176 chunk_t er_key;
177
178 /**
179 * Key for generating auth payload (initiator)
180 */
181 chunk_t pi_key;
182
183 /**
184 * Key for generating auth payload (responder)
185 */
186 chunk_t pr_key;
187
188 } secrets;
189
190 /**
191 * next message id to receive
192 */
193 u_int32_t message_id_in;
194
195 /**
196 * next message id to send
197 */
198 u_int32_t message_id_out;
199
200 /**
201 * a logger for this IKE_SA
202 */
203 logger_t *logger;
204 };
205
206
207 /**
208 * @brief implements function process_message of protected_ike_sa_t
209 */
210 static status_t process_message (private_ike_sa_t *this, message_t *message)
211 {
212 u_int32_t message_id;
213 exchange_type_t exchange_type;
214 bool is_request;
215 status_t status;
216
217 /* we must process each request or response from remote host */
218
219 /* find out type of message (request or response) */
220 is_request = message->get_request(message);
221 exchange_type = message->get_exchange_type(message);
222
223 this->logger->log(this->logger, CONTROL|MORE, "Process %s message of exchange type %s",(is_request) ? "REQUEST" : "RESPONSE",mapping_find(exchange_type_m,exchange_type));
224
225 message_id = message->get_message_id(message);
226
227 /*
228 * It has to be checked, if the message has to be resent cause of lost packets!
229 */
230 if (is_request && ( message_id == (this->message_id_in - 1)))
231 {
232 /* message can be resent ! */
233 this->logger->log(this->logger, CONTROL|MORE, "Resent message detected. Send stored reply");
234 return (this->resend_last_reply(this));
235 }
236
237 /* Now, the message id is checked for request AND reply */
238 if (is_request)
239 {
240 /* In a request, the message has to be this->message_id_in (other case is already handled) */
241 if (message_id != this->message_id_in)
242 {
243 this->logger->log(this->logger, ERROR | MORE, "Message request with message id %d received, but %d expected",message_id,this->message_id_in);
244 return FAILED;
245 }
246 }
247 else
248 {
249 /* In a reply, the message has to be this->message_id_out -1 cause it is the reply to the last sent message*/
250 if (message_id != (this->message_id_out - 1))
251 {
252 this->logger->log(this->logger, ERROR | MORE, "Message reply with message id %d received, but %d expected",message_id,this->message_id_in);
253 return FAILED;
254 }
255 }
256
257 /* now the message is processed by the current state object */
258 /* the current state does change the current change to the next one*/
259 status = this->current_state->process_message(this->current_state,message);
260
261 return status;
262 }
263
264 /**
265 * @brief Implements function build_message of protected_ike_sa_t.
266 */
267 static status_t build_message(private_ike_sa_t *this, exchange_type_t type, bool request, message_t **message)
268 {
269 status_t status;
270 message_t *new_message;
271 host_t *source, *destination;
272
273 this ->logger->log(this->logger, CONTROL|MORE, "build empty message");
274 new_message = message_create();
275 if (new_message == NULL)
276 {
277 this->logger->log(this->logger, ERROR, "Fatal error: could not create empty message object");
278 return OUT_OF_RES;
279 }
280
281 status = this->me.host->clone(this->me.host, &source);
282 if (status != SUCCESS)
283 {
284 this->logger->log(this->logger, ERROR, "Fatal error: could not clone my host information");
285 new_message->destroy(new_message);
286 return status;
287 }
288 status = this->other.host->clone(this->other.host, &destination);
289 if (status != SUCCESS)
290 {
291 this->logger->log(this->logger, ERROR, "Fatal error: could not clone other host information");
292 source->destroy(source);
293 new_message->destroy(new_message);
294 return status;
295 }
296
297 new_message->set_source(new_message, source);
298 new_message->set_destination(new_message, destination);
299
300 new_message->set_exchange_type(new_message, type);
301 new_message->set_request(new_message, request);
302
303 new_message->set_message_id(new_message, (request) ? this->message_id_out : this->message_id_in);
304
305 status = new_message->set_ike_sa_id(new_message, this->ike_sa_id);
306 if (status != SUCCESS)
307 {
308 this->logger->log(this->logger, ERROR, "Fatal error: could not set ike_sa_id of message");
309 new_message->destroy(new_message);
310 return status;
311 }
312
313 *message = new_message;
314
315 return SUCCESS;
316 }
317
318 /**
319 * @brief implements function process_configuration of protected_ike_sa_t
320 */
321 static status_t initialize_connection(private_ike_sa_t *this, char *name)
322 {
323 /* work is done in state object of type INITIATOR_INIT */
324 initiator_init_t *current_state;
325 status_t status;
326
327 if (this->current_state->get_state(this->current_state) != INITIATOR_INIT)
328 {
329 return FAILED;
330 }
331
332 current_state = (initiator_init_t *) this->current_state;
333
334 status = current_state->initiate_connection(current_state,name);
335
336 if (status != SUCCESS)
337 {
338 this->create_delete_job(this);
339 }
340 return status;
341 }
342
343 /**
344 * @brief implements function protected_ike_sa_t.get_id
345 */
346 static ike_sa_id_t* get_id(private_ike_sa_t *this)
347 {
348 return this->ike_sa_id;
349 }
350
351 static status_t compute_secrets (private_ike_sa_t *this,chunk_t dh_shared_secret,chunk_t initiator_nonce, chunk_t responder_nonce)
352 {
353 chunk_t concatenated_nonces;
354 chunk_t skeyseed;
355 chunk_t prf_plus_seed;
356 status_t status;
357 u_int64_t initiator_spi;
358 u_int64_t responder_spi;
359 prf_plus_t *prf_plus;
360 chunk_t secrets_raw;
361
362 /*
363 * TODO check length for specific prf's
364 */
365 concatenated_nonces.len = (initiator_nonce.len + responder_nonce.len);
366 concatenated_nonces.ptr = allocator_alloc(concatenated_nonces.len);
367 if (concatenated_nonces.ptr == NULL)
368 {
369 this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for concatenated nonces");
370 return FAILED;
371 }
372 /* first is initiator */
373 memcpy(concatenated_nonces.ptr,initiator_nonce.ptr,initiator_nonce.len);
374 /* second is responder */
375 memcpy(concatenated_nonces.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
376
377 this->logger->log_chunk(this->logger, RAW, "Nonce data", &concatenated_nonces);
378
379
380 /* status of set_key is not checked */
381 status = this->prf->set_key(this->prf,concatenated_nonces);
382
383 status = this->prf->allocate_bytes(this->prf,dh_shared_secret,&skeyseed);
384 if (status != SUCCESS)
385 {
386 allocator_free_chunk(&concatenated_nonces);
387 this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate bytes for skeyseed");
388 return status;
389 }
390 allocator_free_chunk(&concatenated_nonces);
391
392 prf_plus_seed.len = (initiator_nonce.len + responder_nonce.len + 16);
393 prf_plus_seed.ptr = allocator_alloc(prf_plus_seed.len);
394 if (prf_plus_seed.ptr == NULL)
395 {
396 this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for prf+ seed");
397 allocator_free_chunk(&skeyseed);
398 return FAILED;
399 }
400
401 /* first is initiator */
402 memcpy(prf_plus_seed.ptr,initiator_nonce.ptr,initiator_nonce.len);
403 /* second is responder */
404 memcpy(prf_plus_seed.ptr + initiator_nonce.len,responder_nonce.ptr,responder_nonce.len);
405 /* third is initiator spi */
406 initiator_spi = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
407 memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len,&initiator_spi,8);
408 /* fourth is responder spi */
409 responder_spi = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
410 memcpy(prf_plus_seed.ptr + initiator_nonce.len + responder_nonce.len + 8,&responder_spi,8);
411
412 this->logger->log_chunk(this->logger, PRIVATE, "Keyseed", &skeyseed);
413 this->logger->log_chunk(this->logger, PRIVATE, "PRF+ Seed", &prf_plus_seed);
414
415 this->logger->log(this->logger, CONTROL | MOST, "Set new key of prf object");
416 status = this->prf->set_key(this->prf,skeyseed);
417 allocator_free_chunk(&skeyseed);
418 if (status != SUCCESS)
419 {
420 this->logger->log(this->logger, ERROR, "Fatal errror: Could not allocate memory for prf+ seed");
421 allocator_free_chunk(&prf_plus_seed);
422 return FAILED;
423 }
424
425 this->logger->log(this->logger, CONTROL | MOST, "Create new prf+ object");
426 prf_plus = prf_plus_create(this->prf, prf_plus_seed);
427 allocator_free_chunk(&prf_plus_seed);
428 if (prf_plus == NULL)
429 {
430 this->logger->log(this->logger, ERROR, "Fatal errror: prf+ object could not be created");
431 return FAILED;
432 }
433
434 prf_plus->allocate_bytes(prf_plus,100,&secrets_raw);
435
436 this->logger->log_chunk(this->logger, PRIVATE, "Secrets", &secrets_raw);
437
438 allocator_free_chunk(&secrets_raw);
439
440 prf_plus->destroy(prf_plus);
441
442 return SUCCESS;
443 }
444
445 /**
446 * @brief implements function resend_last_reply of protected_ike_sa_t
447 */
448 status_t resend_last_reply (private_ike_sa_t *this)
449 {
450 packet_t *packet;
451 status_t status;
452
453 status = this->last_responded_message->generate(this->last_responded_message, &packet);
454 if (status != SUCCESS)
455 {
456 this->logger->log(this->logger, ERROR, "Could not generate message to resent");
457 return status;
458 }
459
460 status = global_send_queue->add(global_send_queue, packet);
461 if (status != SUCCESS)
462 {
463 this->logger->log(this->logger, ERROR, "Could not add packet to send queue");
464 packet->destroy(packet);
465 return status;
466 }
467 return SUCCESS;
468 }
469
470 status_t create_delete_job (private_ike_sa_t *this)
471 {
472 job_t *delete_job;
473 status_t status;
474
475 this->logger->log(this->logger, CONTROL | MORE, "Going to create job to delete this IKE_SA");
476
477 delete_job = (job_t *) delete_ike_sa_job_create(this->ike_sa_id);
478 if (delete_job == NULL)
479 {
480 this->logger->log(this->logger, ERROR, "Job to delete IKE SA could not be created");
481 return FAILED;
482 }
483
484 status = global_job_queue->add(global_job_queue,delete_job);
485 if (status != SUCCESS)
486 {
487 this->logger->log(this->logger, ERROR, "%s Job to delete IKE SA could not be added to job queue",mapping_find(status_m,status));
488 delete_job->destroy_all(delete_job);
489 return status;
490 }
491 return SUCCESS;
492 }
493
494 /**
495 * Implementation of protected_ike_sa_t.set_new_state.
496 */
497 static void set_new_state (private_ike_sa_t *this, state_t *state)
498 {
499 this->current_state = state;
500 }
501
502 /**
503 * Implementation of protected_ike_sa_t.get_logger.
504 */
505 static logger_t *get_logger (private_ike_sa_t *this)
506 {
507 return this->logger;
508 }
509
510 /**
511 * Implementation of protected_ike_sa_t.get_my_host.
512 */
513 static host_t *get_my_host (private_ike_sa_t *this)
514 {
515 return this->me.host;
516 }
517
518 /**
519 * Implementation of protected_ike_sa_t.get_other_host.
520 */
521 static host_t *get_other_host (private_ike_sa_t *this)
522 {
523 return this->other.host;
524 }
525
526 /**
527 * Implementation of protected_ike_sa_t.set_my_host.
528 */
529 static void set_my_host (private_ike_sa_t *this, host_t *my_host)
530 {
531 if (this->me.host != NULL)
532 {
533 this->me.host->destroy(this->me.host);
534 }
535 this->me.host = my_host;
536 }
537
538 /**
539 * Implementation of protected_ike_sa_t.set_other_host.
540 */
541 static void set_other_host (private_ike_sa_t *this, host_t *other_host)
542 {
543 if (this->other.host != NULL)
544 {
545 this->other.host->destroy(this->other.host);
546 }
547 this->other.host = other_host;
548 }
549
550 /**
551 * Implementation of protected_ike_sa_t.set_prf.
552 */
553 static void set_prf (private_ike_sa_t *this,prf_t *prf)
554 {
555 if (this->prf != NULL)
556 {
557 this->prf->destroy(this->prf);
558 }
559 this->prf = prf;
560 }
561
562 /**
563 * Implementation of protected_ike_sa_t.get_randomizer.
564 */
565 static randomizer_t *get_randomizer (private_ike_sa_t *this)
566 {
567 return this->randomizer;
568 }
569
570 /**
571 * Implementation of protected_ike_sa_t.set_last_requested_message.
572 */
573 static status_t set_last_requested_message (private_ike_sa_t *this,message_t * message)
574 {
575 if ( this->last_requested_message != NULL)
576 {
577 /* destroy message */
578 this ->logger->log(this->logger, CONTROL|MOST, "Destroy stored last requested message");
579 this->last_requested_message->destroy(this->last_requested_message);
580 }
581
582 if (message->get_message_id(message) != this->message_id_out)
583 {
584 this ->logger->log(this->logger, CONTROL|MOST, "last requested message could not be set cause id was not as expected");
585 return FAILED;
586 }
587 this ->logger->log(this->logger, CONTROL|MOST, "replace last requested message with new one");
588 this->last_requested_message = message;
589
590 /* message counter can now be increased */
591 this ->logger->log(this->logger, CONTROL|MOST, "Increate message counter for outgoing messages");
592 this->message_id_out++;
593 return SUCCESS;
594 }
595
596
597 /**
598 * Implementation of protected_ike_sa_t.set_last_responded_message.
599 */
600 static status_t set_last_responded_message (private_ike_sa_t *this,message_t * message)
601 {
602 if ( this->last_responded_message != NULL)
603 {
604 /* destroy message */
605 this ->logger->log(this->logger, CONTROL|MOST, "Destroy stored last responded message");
606 this->last_responded_message->destroy(this->last_responded_message);
607 }
608 if (message->get_message_id(message) != this->message_id_in)
609 {
610 this ->logger->log(this->logger, CONTROL|MOST, "last responded message could not be set cause id was not as expected");
611 return FAILED;
612
613 }
614 this ->logger->log(this->logger, CONTROL|MOST, "replace last responded message with new one");
615 this->last_responded_message = message;
616
617 /* message counter can now be increased */
618 this ->logger->log(this->logger, CONTROL|MOST, "Increate message counter for incoming messages");
619 this->message_id_in++;
620
621 return SUCCESS;
622 }
623
624
625 /**
626 * @brief implements function destroy of protected_ike_sa_t
627 */
628 static status_t destroy (private_ike_sa_t *this)
629 {
630
631 this->logger->log(this->logger, CONTROL | MORE, "Going to destroy IKE_SA");
632
633 /* destroy child sa's */
634 this->logger->log(this->logger, CONTROL | MOST, "Destroy all child_sa's");
635 while (this->child_sas->get_count(this->child_sas) > 0)
636 {
637 void *child_sa;
638 if (this->child_sas->remove_first(this->child_sas,&child_sa) != SUCCESS)
639 {
640 break;
641 }
642 /* destroy child sa */
643 }
644 this->child_sas->destroy(this->child_sas);
645
646 this->logger->log(this->logger, CONTROL | MOST, "Destroy secrets");
647 if (this->secrets.d_key.ptr != NULL)
648 {
649 allocator_free(this->secrets.d_key.ptr);
650 }
651 if (this->secrets.ai_key.ptr != NULL)
652 {
653 allocator_free(this->secrets.ai_key.ptr);
654 }
655 if (this->secrets.ar_key.ptr != NULL)
656 {
657 allocator_free(this->secrets.ar_key.ptr);
658 }
659 if (this->secrets.ei_key.ptr != NULL)
660 {
661 allocator_free(this->secrets.ei_key.ptr);
662 }
663 if (this->secrets.er_key.ptr != NULL)
664 {
665 allocator_free(this->secrets.er_key.ptr);
666 }
667 if (this->secrets.pi_key.ptr != NULL)
668 {
669 allocator_free(this->secrets.pi_key.ptr);
670 }
671 if (this->secrets.pr_key.ptr != NULL)
672 {
673 allocator_free(this->secrets.pr_key.ptr);
674 }
675
676 if ( this->crypter_initiator != NULL)
677 {
678 this->logger->log(this->logger, CONTROL | MOST, "Destroy initiator crypter");
679 this->crypter_initiator->destroy(this->crypter_initiator);
680 }
681
682 if ( this->crypter_responder != NULL)
683 {
684 this->logger->log(this->logger, CONTROL | MOST, "Destroy responder crypter");
685 this->crypter_responder->destroy(this->crypter_responder);
686 }
687
688 if ( this->signer_initiator != NULL)
689 {
690 this->logger->log(this->logger, CONTROL | MOST, "Destroy initiator signer");
691 this->signer_initiator->destroy(this->signer_initiator);
692 }
693
694 if (this->signer_responder != NULL)
695 {
696 this->logger->log(this->logger, CONTROL | MOST, "Destroy responder signer");
697 this->signer_responder->destroy(this->signer_responder);
698 }
699
700 if (this->prf != NULL)
701 {
702 this->logger->log(this->logger, CONTROL | MOST, "Destroy prf");
703 this->prf->destroy(this->prf);
704 }
705
706 /* destroy ike_sa_id */
707 this->logger->log(this->logger, CONTROL | MOST, "Destroy assigned ike_sa_id");
708 this->ike_sa_id->destroy(this->ike_sa_id);
709
710 /* destroy stored requested message */
711 if (this->last_requested_message != NULL)
712 {
713 this->logger->log(this->logger, CONTROL | MOST, "Destroy last requested message");
714 this->last_requested_message->destroy(this->last_requested_message);
715 }
716
717 /* destroy stored responded messages */
718 if (this->last_responded_message != NULL)
719 {
720 this->logger->log(this->logger, CONTROL | MOST, "Destroy last responded message");
721 this->last_responded_message->destroy(this->last_responded_message);
722 }
723
724 this->logger->log(this->logger, CONTROL | MOST, "Destroy randomizer");
725 this->randomizer->destroy(this->randomizer);
726
727 if (this->me.host != NULL)
728 {
729 this->logger->log(this->logger, CONTROL | MOST, "Destroy host informations of me");
730 this->me.host->destroy(this->me.host);
731 }
732
733 if (this->other.host != NULL)
734 {
735 this->logger->log(this->logger, CONTROL | MOST, "Destroy host informations of other");
736 this->other.host->destroy(this->other.host);
737 }
738
739 this->logger->log(this->logger, CONTROL | MOST, "Destroy current state object");
740 this->current_state->destroy(this->current_state);
741
742 this->logger->log(this->logger, CONTROL | MOST, "Destroy logger of IKE_SA");
743
744 global_logger_manager->destroy_logger(global_logger_manager, this->logger);
745
746 allocator_free(this);
747 return SUCCESS;
748 }
749
750 /*
751 * Described in Header
752 */
753 ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
754 {
755 private_ike_sa_t *this = allocator_alloc_thing(private_ike_sa_t);
756 if (this == NULL)
757 {
758 return NULL;
759 }
760
761 /* Public functions */
762 this->protected.public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message;
763 this->protected.public.initialize_connection = (status_t(*)(ike_sa_t*, char*)) initialize_connection;
764 this->protected.public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id;
765 this->protected.public.destroy = (status_t(*)(ike_sa_t*))destroy;
766
767 /* protected functions */
768 this->protected.build_message = (status_t (*) (protected_ike_sa_t *, exchange_type_t , bool , message_t **)) build_message;
769 this->protected.compute_secrets = (status_t (*) (protected_ike_sa_t *,chunk_t ,chunk_t , chunk_t )) compute_secrets;
770 this->protected.get_logger = (logger_t *(*) (protected_ike_sa_t *)) get_logger;
771 this->protected.get_my_host = (host_t *(*) (protected_ike_sa_t *)) get_my_host;
772 this->protected.get_other_host = (host_t *(*) (protected_ike_sa_t *)) get_other_host;
773 this->protected.set_my_host = (void(*) (protected_ike_sa_t *,host_t *)) set_my_host;
774 this->protected.set_other_host = (void(*) (protected_ike_sa_t *, host_t *)) set_other_host;
775 this->protected.get_randomizer = (randomizer_t *(*) (protected_ike_sa_t *)) get_randomizer;
776 this->protected.set_last_requested_message = (status_t (*) (protected_ike_sa_t *,message_t *)) set_last_requested_message;
777 this->protected.set_last_responded_message = (status_t (*) (protected_ike_sa_t *,message_t *)) set_last_responded_message;
778 this->protected.set_prf = (void (*) (protected_ike_sa_t *,prf_t *)) set_prf;
779 this->protected.set_new_state = (void (*) (protected_ike_sa_t *,state_t *)) set_new_state;
780
781 /* private functions */
782 this->resend_last_reply = resend_last_reply;
783 this->create_delete_job = create_delete_job;
784
785
786 /* initialize private fields */
787 this->logger = global_logger_manager->create_logger(global_logger_manager, IKE_SA, NULL);
788 if (this->logger == NULL)
789 {
790 allocator_free(this);
791 }
792
793 if (ike_sa_id->clone(ike_sa_id,&(this->ike_sa_id)) != SUCCESS)
794 {
795 this->logger->log(this->logger, ERROR, "Fatal error: Could not clone ike_sa_id");
796 global_logger_manager->destroy_logger(global_logger_manager,this->logger);
797 allocator_free(this);
798 return NULL;
799 }
800 this->child_sas = linked_list_create();
801 if (this->child_sas == NULL)
802 {
803 this->logger->log(this->logger, ERROR, "Fatal error: Could not create list for child_sa's");
804 this->ike_sa_id->destroy(this->ike_sa_id);
805 global_logger_manager->destroy_logger(global_logger_manager,this->logger);
806 allocator_free(this);
807 return NULL;
808 }
809 this->randomizer = randomizer_create();
810 if (this->randomizer == NULL)
811 {
812 this->logger->log(this->logger, ERROR, "Fatal error: Could not create list for child_sa's");
813 this->child_sas->destroy(this->child_sas);
814 this->ike_sa_id->destroy(this->ike_sa_id);
815 global_logger_manager->destroy_logger(global_logger_manager,this->logger);
816 allocator_free(this);
817 }
818
819 this->me.host = NULL;
820 this->other.host = NULL;
821 this->last_requested_message = NULL;
822 this->last_responded_message = NULL;
823 this->message_id_out = 0;
824 this->message_id_in = 0;
825 this->secrets.d_key.ptr = NULL;
826 this->secrets.d_key.len = 0;
827 this->secrets.ai_key.ptr = NULL;
828 this->secrets.ai_key.len = 0;
829 this->secrets.ar_key.ptr = NULL;
830 this->secrets.ar_key.len = 0;
831 this->secrets.ei_key.ptr = NULL;
832 this->secrets.ei_key.len = 0;
833 this->secrets.er_key.ptr = NULL;
834 this->secrets.er_key.len = 0;
835 this->secrets.pi_key.ptr = NULL;
836 this->secrets.pi_key.len = 0;
837 this->secrets.pr_key.ptr = NULL;
838 this->secrets.pr_key.len = 0;
839 this->crypter_initiator = NULL;
840 this->crypter_responder = NULL;
841 this->signer_initiator = NULL;
842 this->signer_responder = NULL;
843 this->prf = NULL;
844
845
846
847
848 /* at creation time, IKE_SA is in a initiator state */
849 if (ike_sa_id->is_initiator(ike_sa_id))
850 {
851 this->current_state = (state_t *) initiator_init_create(&(this->protected));
852 }
853 else
854 {
855 this->current_state = (state_t *) responder_init_create(&(this->protected));
856 }
857
858 if (this->current_state == NULL)
859 {
860 this->logger->log(this->logger, ERROR, "Fatal error: Could not create state object");
861 this->child_sas->destroy(this->child_sas);
862 this->ike_sa_id->destroy(this->ike_sa_id);
863 global_logger_manager->destroy_logger(global_logger_manager,this->logger);
864 this->randomizer->destroy(this->randomizer);
865 allocator_free(this);
866 }
867
868
869 return &(this->protected.public);
870 }