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