fixed crypter/signer in/out to conform with standard
[strongswan.git] / src / charon / sa / ike_sa.c
1 /**
2 * @file ike_sa.c
3 *
4 * @brief Implementation of ike_sa_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
10 * Copyright (C) 2005-2006 Martin Willi
11 * Copyright (C) 2005 Jan Hutter
12 * Hochschule fuer Technik Rapperswil
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 */
24
25 #include <sys/time.h>
26 #include <string.h>
27
28 #include "ike_sa.h"
29
30 #include <types.h>
31 #include <daemon.h>
32 #include <definitions.h>
33 #include <utils/linked_list.h>
34 #include <utils/logger_manager.h>
35 #include <crypto/diffie_hellman.h>
36 #include <crypto/prf_plus.h>
37 #include <crypto/crypters/crypter.h>
38 #include <crypto/hashers/hasher.h>
39 #include <encoding/payloads/sa_payload.h>
40 #include <encoding/payloads/nonce_payload.h>
41 #include <encoding/payloads/ke_payload.h>
42 #include <encoding/payloads/delete_payload.h>
43 #include <encoding/payloads/transform_substructure.h>
44 #include <encoding/payloads/transform_attribute.h>
45 #include <encoding/payloads/ts_payload.h>
46 #include <sa/transactions/transaction.h>
47 #include <sa/transactions/ike_sa_init.h>
48 #include <sa/transactions/delete_ike_sa.h>
49 #include <sa/transactions/create_child_sa.h>
50 #include <sa/transactions/delete_child_sa.h>
51 #include <sa/transactions/dead_peer_detection.h>
52 #include <queues/jobs/retransmit_request_job.h>
53 #include <queues/jobs/delete_established_ike_sa_job.h>
54 #include <queues/jobs/delete_half_open_ike_sa_job.h>
55 #include <queues/jobs/send_dpd_job.h>
56 #include <queues/jobs/send_keepalive_job.h>
57
58
59 /**
60 * String mappings for ike_sa_state_t.
61 */
62 mapping_t ike_sa_state_m[] = {
63 {SA_CREATED, "CREATED"},
64 {SA_CONNECTING, "CONNECTING"},
65 {SA_ESTABLISHED, "ESTABLISHED"},
66 {SA_DELETING, "DELETING"},
67 {MAPPING_END, NULL}
68 };
69
70
71 typedef struct private_ike_sa_t private_ike_sa_t;
72
73 /**
74 * Private data of an ike_sa_t object.
75 */
76 struct private_ike_sa_t {
77
78 /**
79 * Public members
80 */
81 ike_sa_t public;
82
83 /**
84 * Identifier for the current IKE_SA.
85 */
86 ike_sa_id_t *ike_sa_id;
87
88 /**
89 * Linked List containing the child sa's of the current IKE_SA.
90 */
91 linked_list_t *child_sas;
92
93 /**
94 * Current state of the IKE_SA
95 */
96 ike_sa_state_t state;
97
98 /**
99 * Connection definition used for this IKE_SA
100 */
101 connection_t *connection;
102
103 /**
104 * Policy definition used for this IKE_SA
105 */
106 policy_t *policy;
107
108 /**
109 * crypter for inbound traffic
110 */
111 crypter_t *crypter_in;
112
113 /**
114 * crypter for outbound traffic
115 */
116 crypter_t *crypter_out;
117
118 /**
119 * Signer for inbound traffic
120 */
121 signer_t *signer_in;
122
123 /**
124 * Signer for outbound traffic
125 */
126 signer_t *signer_out;
127
128 /**
129 * Multi purpose prf, set key, use it, forget it
130 */
131 prf_t *prf;
132
133 /**
134 * Prf function for derivating keymat child SAs
135 */
136 prf_t *child_prf;
137
138 /**
139 * PRF, with key set to pi_key, used for authentication
140 */
141 prf_t *prf_auth_i;
142
143 /**
144 * PRF, with key set to pr_key, used for authentication
145 */
146 prf_t *prf_auth_r;
147
148 /**
149 * A logger for this IKE_SA.
150 */
151 logger_t *logger;
152
153 /**
154 * NAT hasher.
155 */
156 hasher_t *nat_hasher;
157
158 /**
159 * NAT status of local host.
160 */
161 bool nat_here;
162
163 /**
164 * NAT status of remote host.
165 */
166 bool nat_there;
167
168 /**
169 * message ID for next outgoung request
170 */
171 u_int32_t message_id_out;
172
173 /**
174 * Timestamp of last IKE message received on this SA
175 */
176 time_t time_inbound;
177
178 /**
179 * Timestamp of last IKE message sent on this SA
180 */
181 time_t time_outbound;
182
183 /**
184 * List of queued transactions to process
185 */
186 linked_list_t *transaction_queue;
187
188 /**
189 * Transaction currently initiated
190 * (only one supported yet, window size = 1)
191 */
192 transaction_t *transaction_out;
193
194 /**
195 * last transaction initiated by peer processed.
196 * (only one supported yet, window size = 1)
197 * Stored for retransmission.
198 */
199 transaction_t *transaction_in;
200
201 /**
202 * Next incoming transaction expected. Used to
203 * do multi transaction operations.
204 */
205 transaction_t *transaction_in_next;
206 };
207
208 /**
209 * get the time of the latest traffic processed by the kernel
210 */
211 static time_t get_esp_time(private_ike_sa_t* this, bool inbound)
212 {
213 iterator_t *iterator;
214 child_sa_t *child_sa;
215 time_t latest = 0, use_time;
216
217 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
218 while (iterator->iterate(iterator, (void**)&child_sa))
219 {
220 if (child_sa->get_use_time(child_sa, inbound, &use_time) == SUCCESS)
221 {
222 latest = max(latest, use_time);
223 }
224 }
225 iterator->destroy(iterator);
226
227 return latest;
228 }
229
230 /**
231 * get the time of the latest received traffice
232 */
233 static time_t get_time_inbound(private_ike_sa_t *this)
234 {
235 return max(this->time_inbound, get_esp_time(this, TRUE));
236 }
237
238 /**
239 * get the time of the latest sent traffic
240 */
241 static time_t get_time_outbound(private_ike_sa_t *this)
242 {
243 return max(this->time_outbound, get_esp_time(this, FALSE));
244 }
245
246
247 /**
248 * Update connection host, as addresses may change (NAT)
249 */
250 static void update_hosts(private_ike_sa_t *this, host_t *me, host_t *other)
251 {
252 /*
253 * Quoting RFC 4306:
254 *
255 * 2.11. Address and Port Agility
256 *
257 * IKE runs over UDP ports 500 and 4500, and implicitly sets up ESP and
258 * AH associations for the same IP addresses it runs over. The IP
259 * addresses and ports in the outer header are, however, not themselves
260 * cryptographically protected, and IKE is designed to work even through
261 * Network Address Translation (NAT) boxes. An implementation MUST
262 * accept incoming requests even if the source port is not 500 or 4500,
263 * and MUST respond to the address and port from which the request was
264 * received. It MUST specify the address and port at which the request
265 * was received as the source address and port in the response. IKE
266 * functions identically over IPv4 or IPv6.
267 *
268 * [...]
269 *
270 * There are cases where a NAT box decides to remove mappings that
271 * are still alive (for example, the keepalive interval is too long,
272 * or the NAT box is rebooted). To recover in these cases, hosts
273 * that are not behind a NAT SHOULD send all packets (including
274 * retransmission packets) to the IP address and port from the last
275 * valid authenticated packet from the other end (i.e., dynamically
276 * update the address). A host behind a NAT SHOULD NOT do this
277 * because it opens a DoS attack possibility. Any authenticated IKE
278 * packet or any authenticated UDP-encapsulated ESP packet can be
279 * used to detect that the IP address or the port has changed.
280 */
281 host_t *old_other = NULL;
282 iterator_t *iterator = NULL;
283 child_sa_t *child_sa = NULL;
284 int my_changes, other_changes;
285
286 my_changes = me->get_differences(me, this->connection->get_my_host(this->connection));
287
288 old_other = this->connection->get_other_host(this->connection);
289 other_changes = other->get_differences(other, old_other);
290
291 if (!my_changes && !other_changes)
292 {
293 return;
294 }
295
296 if (my_changes)
297 {
298 this->connection->update_my_host(this->connection, me->clone(me));
299 }
300
301 if (!this->nat_here)
302 {
303 /* update without restrictions if we are not NATted */
304 if (other_changes)
305 {
306 this->connection->update_other_host(this->connection, other->clone(other));
307 }
308 }
309 else
310 {
311 /* if we are natted, only port may change */
312 if (other_changes & HOST_DIFF_ADDR)
313 {
314 return;
315 }
316 else if (other_changes & HOST_DIFF_PORT)
317 {
318 old_other->set_port(old_other, other->get_port(other));
319 }
320 }
321 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
322 while (iterator->iterate(iterator, (void**)&child_sa))
323 {
324 child_sa->update_hosts(child_sa,
325 this->connection->get_my_host(this->connection),
326 this->connection->get_other_host(this->connection),
327 my_changes, other_changes);
328 /* TODO: what to do if update fails? Delete CHILD_SA? */
329 }
330 iterator->destroy(iterator);
331 }
332
333 /**
334 * send a request and schedule retransmission
335 */
336 static status_t transmit_request(private_ike_sa_t *this)
337 {
338 message_t *request;
339 packet_t *packet;
340 status_t status;
341 retransmit_request_job_t *job;
342 u_int32_t transmitted;
343 u_int32_t timeout;
344 transaction_t *transaction = this->transaction_out;
345 u_int32_t message_id = transaction->get_message_id(transaction);
346
347 transmitted = transaction->requested(transaction);
348 timeout = charon->configuration->get_retransmit_timeout(charon->configuration,
349 transmitted);
350 if (timeout == 0)
351 {
352 this->logger->log(this->logger, ERROR,
353 "giving up after %d retransmits, deleting IKE_SA",
354 transmitted - 1);
355 return DESTROY_ME;
356 }
357
358 status = transaction->get_request(transaction, &request);
359 if (status != SUCCESS)
360 {
361 return status;
362 }
363 /* if we retransmit, the request is already generated */
364 if (transmitted == 0)
365 {
366 status = request->generate(request, this->crypter_out, this->signer_out, &packet);
367 if (status != SUCCESS)
368 {
369 return FAILED;
370 }
371 }
372 else
373 {
374 this->logger->log(this->logger, CONTROL,
375 "sending retransmit %d for %s request with message ID %d",
376 transmitted,
377 mapping_find(exchange_type_m, request->get_exchange_type(request)),
378 message_id);
379 packet = request->get_packet(request);
380 }
381 /* finally send */
382 charon->send_queue->add(charon->send_queue, packet);
383 this->time_outbound = time(NULL);
384
385 /* schedule retransmission job */
386 job = retransmit_request_job_create(message_id, this->ike_sa_id);
387 charon->event_queue->add_relative(charon->event_queue, (job_t*)job, timeout);
388 return SUCCESS;
389 }
390
391 /**
392 * Implementation of ike_sa.retransmit_request.
393 */
394 static status_t retransmit_request(private_ike_sa_t *this, u_int32_t message_id)
395 {
396 if (this->transaction_out == NULL ||
397 this->transaction_out->get_message_id(this->transaction_out) != message_id)
398 {
399 /* no retransmit necessary, transaction did already complete */
400 return SUCCESS;
401 }
402 return transmit_request(this);
403 }
404
405 /**
406 * Check for transactions in the queue and initiate the first transaction found.
407 */
408 static status_t process_transaction_queue(private_ike_sa_t *this)
409 {
410 if (this->transaction_out)
411 {
412 /* already a transaction in progress */
413 return SUCCESS;
414 }
415
416 while (TRUE)
417 {
418 if (this->transaction_queue->remove_first(this->transaction_queue,
419 (void**)&this->transaction_out) != SUCCESS)
420 {
421 /* transaction queue empty */
422 return SUCCESS;
423 }
424 switch (transmit_request(this))
425 {
426 case SUCCESS:
427 return SUCCESS;
428 case DESTROY_ME:
429 /* critical, IKE_SA unusable, destroy immediately */
430 this->logger->log(this->logger, ERROR,
431 "transaction initiaton failed, deleting IKE_SA");
432 return DESTROY_ME;
433 default:
434 /* discard transaction, process next one */
435 this->logger->log(this->logger, ERROR,
436 "transaction initiation failed, discarded");
437 this->transaction_out->destroy(this->transaction_out);
438 this->transaction_out = NULL;
439 /* handle next transaction */
440 continue;
441 }
442 }
443 }
444
445 /**
446 * Queue a new transaction and execute the next outstanding transaction
447 */
448 static status_t queue_transaction(private_ike_sa_t *this, transaction_t *transaction, bool prefer)
449 {
450 /* inject next transaction */
451 if (transaction)
452 {
453 if (prefer)
454 {
455 this->transaction_queue->insert_first(this->transaction_queue, transaction);
456 }
457 else
458 {
459 this->transaction_queue->insert_last(this->transaction_queue, transaction);
460 }
461 }
462 /* process a transaction */
463 return process_transaction_queue(this);
464 }
465
466 /**
467 * process an incoming request.
468 */
469 static status_t process_request(private_ike_sa_t *this, message_t *request)
470 {
471 transaction_t *last, *current = NULL;
472 message_t *response;
473 packet_t *packet;
474 u_int32_t request_mid;
475 status_t status;
476
477 request_mid = request->get_message_id(request);
478 last = this->transaction_in;
479
480 /* check if message ID is correct */
481 if (last)
482 {
483 u_int32_t last_mid = last->get_message_id(last);
484
485 if (last_mid == request_mid)
486 {
487 /* retransmit detected */
488 this->logger->log(this->logger, ERROR,
489 "received retransmitted request for message ID %d, retransmitting response",
490 request_mid);
491 last->get_response(last, request, &response, &this->transaction_in_next);
492 packet = response->get_packet(response);
493 charon->send_queue->add(charon->send_queue, packet);
494 this->time_outbound = time(NULL);
495 return SUCCESS;
496 }
497
498 if (last_mid > request_mid)
499 {
500 /* something seriously wrong here, message id may not decrease */
501 this->logger->log(this->logger, ERROR,
502 "received request with message ID %d, excepted %d, ingored",
503 request_mid, last_mid + 1);
504 return FAILED;
505 }
506 /* we allow jumps in message IDs, as long as they are incremental */
507 if (last_mid + 1 < request_mid)
508 {
509 this->logger->log(this->logger, ERROR,
510 "received request with message ID %d, excepted %d",
511 request_mid, last_mid + 1);
512 }
513 }
514 else
515 {
516 if (request_mid != 0)
517 {
518 /* warn, but allow it */
519 this->logger->log(this->logger, CONTROL,
520 "first received request has message ID %d, excepted 0",
521 request_mid);
522 }
523 }
524
525 /* check if we already have a pre-created transaction for this request */
526 if (this->transaction_in_next)
527 {
528 u_int32_t trans_mid = this->transaction_in_next->get_message_id(this->transaction_in_next);
529
530 /* check message id consistency */
531 if (trans_mid == request_mid)
532 {
533 /* use it */
534 current = this->transaction_in_next;
535 }
536 else
537 {
538 /* discard queued transaction */
539 this->transaction_in_next->destroy(this->transaction_in_next);
540 }
541 this->transaction_in_next = NULL;
542 }
543 /* create new transaction if "next" unusable */
544 if (current == NULL)
545 {
546 current = transaction_create(&this->public, request);
547 if (current == NULL)
548 {
549 this->logger->log(this->logger, ERROR,
550 "no idea how to handle received message (%d), ignored",
551 request->get_exchange_type(request));
552 return FAILED;
553 }
554 }
555
556 /* send message. get_request() always gives a valid response */
557 status = current->get_response(current, request, &response, &this->transaction_in_next);
558 if (response->generate(response, this->crypter_out, this->signer_out, &packet) != SUCCESS)
559 {
560 this->logger->log(this->logger, ERROR,
561 "response generation failed, discarding transaction");
562 current->destroy(current);
563 return FAILED;
564 }
565
566 charon->send_queue->add(charon->send_queue, packet);
567 this->time_outbound = time(NULL);
568 /* act depending on transaction result */
569 switch (status)
570 {
571 case DESTROY_ME:
572 /* transactions says we should destroy the IKE_SA, so do it */
573 current->destroy(current);
574 return DESTROY_ME;
575 default:
576 /* store for retransmission, destroy old transaction */
577 this->transaction_in = current;
578 if (last)
579 {
580 last->destroy(last);
581 }
582 return SUCCESS;
583 }
584 }
585
586 /**
587 * process an incoming response
588 */
589 static status_t process_response(private_ike_sa_t *this, message_t *response)
590 {
591 transaction_t *current, *new = NULL;
592
593 current = this->transaction_out;
594 /* check if message ID is that of our currently active transaction */
595 if (current == NULL ||
596 current->get_message_id(current) !=
597 response->get_message_id(response))
598 {
599 this->logger->log(this->logger, ERROR,
600 "received response with message ID %d not requested, ignored");
601 return FAILED;
602 }
603
604 switch (current->conclude(current, response, &new))
605 {
606 case DESTROY_ME:
607 /* state requested to destroy IKE_SA */
608 return DESTROY_ME;
609 default:
610 /* discard transaction, process next one */
611 break;
612 }
613 /* transaction comleted, remove */
614 current->destroy(current);
615 this->transaction_out = NULL;
616
617 /* if conclude() created a new transaction, we increment the message_id
618 * counter, as the new transaction used the next one */
619 if (new)
620 {
621 this->message_id_out = new->get_message_id(new) + 1;;
622 }
623
624 /* queue new transaction */
625 return queue_transaction(this, new, TRUE);
626 }
627
628 /**
629 * send a notify back to the sender
630 */
631 static void send_notify_response(private_ike_sa_t *this,
632 message_t *request,
633 notify_type_t type)
634 {
635 notify_payload_t *notify;
636 message_t *response;
637 host_t *src, *dst;
638 packet_t *packet;
639
640 response = message_create();
641 dst = request->get_source(request);
642 src = request->get_destination(request);
643 response->set_source(response, src->clone(src));
644 response->set_destination(response, dst->clone(dst));
645 response->set_exchange_type(response, request->get_exchange_type(request));
646 response->set_request(response, FALSE);
647 response->set_message_id(response, request->get_message_id(request));
648 response->set_ike_sa_id(response, this->ike_sa_id);
649 notify = notify_payload_create_from_protocol_and_type(PROTO_NONE, type);
650 response->add_payload(response, (payload_t *)notify);
651 if (response->generate(response, this->crypter_out, this->signer_out, &packet) != SUCCESS)
652 {
653 response->destroy(response);
654 return;
655 }
656 charon->send_queue->add(charon->send_queue, packet);
657 this->time_outbound = time(NULL);
658 response->destroy(response);
659 return;
660 }
661
662
663 /**
664 * Implementation of ike_sa_t.process_message.
665 */
666 static status_t process_message(private_ike_sa_t *this, message_t *message)
667 {
668 status_t status;
669 bool is_request;
670
671 is_request = message->get_request(message);
672
673 status = message->parse_body(message, this->crypter_in, this->signer_in);
674 if (status != SUCCESS)
675 {
676 switch (status)
677 {
678 case NOT_SUPPORTED:
679 this->logger->log(this->logger, ERROR,
680 "ciritcal unknown payloads found");
681 if (is_request)
682 {
683 send_notify_response(this, message, UNSUPPORTED_CRITICAL_PAYLOAD);
684 }
685 break;
686 case PARSE_ERROR:
687 this->logger->log(this->logger, ERROR,
688 "message parsing failed");
689 if (is_request)
690 {
691 send_notify_response(this, message, INVALID_SYNTAX);
692 }
693 break;
694 case VERIFY_ERROR:
695 this->logger->log(this->logger, ERROR,
696 "message verification failed");
697 if (is_request)
698 {
699 send_notify_response(this, message, INVALID_SYNTAX);
700 }
701 break;
702 case FAILED:
703 this->logger->log(this->logger, ERROR,
704 "integrity check failed");
705 /* ignored */
706 break;
707 case INVALID_STATE:
708 this->logger->log(this->logger, ERROR,
709 "found encrypted message, but no keys available");
710 if (is_request)
711 {
712 send_notify_response(this, message, INVALID_SYNTAX);
713 }
714 default:
715 break;
716 }
717 this->logger->log(this->logger, ERROR,
718 "%s %s with message ID %d processing failed",
719 mapping_find(exchange_type_m, message->get_exchange_type(message)),
720 message->get_request(message) ? "request" : "response",
721 message->get_message_id(message));
722 }
723 else
724 {
725 /* check if message is trustworthy, and update connection information */
726 if ((this->state == SA_CREATED && this->connection) ||
727 message->get_exchange_type(message) != IKE_SA_INIT)
728 {
729 update_hosts(this, message->get_destination(message),
730 message->get_source(message));
731 this->time_inbound = time(NULL);
732 }
733 if (is_request)
734 {
735 status = process_request(this, message);
736 }
737 else
738 {
739 status = process_response(this, message);
740 }
741 }
742 return status;
743 }
744
745 /**
746 * Implementation of ike_sa_t.initiate.
747 */
748 static status_t initiate(private_ike_sa_t *this, connection_t *connection)
749 {
750 ike_sa_init_t *ike_sa_init;
751
752 /* set connection and policy */
753 this->connection = connection;
754 this->policy = charon->policies->get_policy_by_name(charon->policies,
755 this->connection->get_name(this->connection));
756 if (this->policy == NULL)
757 {
758 this->logger->log(this->logger, ERROR,
759 "no policy found for connection %s, aborting",
760 connection->get_name(connection));
761 return DESTROY_ME;
762 }
763 this->message_id_out = 0;
764 ike_sa_init = ike_sa_init_create(&this->public, this->message_id_out++);
765 return queue_transaction(this, (transaction_t*)ike_sa_init, TRUE);
766 }
767
768 /**
769 * Implementation of ike_sa_t.send_dpd
770 */
771 static status_t send_dpd(private_ike_sa_t *this)
772 {
773 send_dpd_job_t *job;
774 time_t diff, interval;
775 status_t status = SUCCESS;
776
777 interval = charon->configuration->get_dpd_interval(charon->configuration);
778
779 if (this->transaction_out)
780 {
781 /* there is a transaction in progress. Come back later */
782 diff = 0;
783 }
784 else
785 {
786 /* check if there was any inbound traffic */
787 time_t last_in, now;
788 last_in = get_time_inbound(this);
789 now = time(NULL);
790 diff = now - last_in;
791 if (diff >= interval)
792 {
793 /* to long ago, initiate dead peer detection */
794 dead_peer_detection_t *dpd;
795 this->logger->log(this->logger, CONTROL, "sending DPD request");
796 dpd = dead_peer_detection_create(&this->public, this->message_id_out++);
797 status = queue_transaction(this, (transaction_t*)dpd, FALSE);
798 diff = 0;
799 }
800 }
801 /* recheck in "interval" seconds */
802 job = send_dpd_job_create(this->ike_sa_id);
803 charon->event_queue->add_relative(charon->event_queue, (job_t*)job,
804 (interval - diff) * 1000);
805 return SUCCESS;
806 }
807
808 /**
809 * Implementation of ike_sa_t.send_keepalive
810 */
811 static void send_keepalive(private_ike_sa_t *this)
812 {
813 send_keepalive_job_t *job;
814 time_t last_out, now, diff, interval;
815
816 last_out = get_time_outbound(this);
817 now = time(NULL);
818
819 diff = now - last_out;
820 interval = charon->configuration->get_keepalive_interval(charon->configuration);
821
822 if (diff >= interval)
823 {
824 host_t *me, *other;
825 packet_t *packet;
826 chunk_t data;
827
828 packet = packet_create();
829 me = this->connection->get_my_host(this->connection);
830 other = this->connection->get_other_host(this->connection);
831 packet->set_source(packet, me->clone(me));
832 packet->set_destination(packet, other->clone(other));
833 data.ptr = malloc(1);
834 data.ptr[0] = 0xFF;
835 data.len = 1;
836 packet->set_data(packet, data);
837 charon->send_queue->add(charon->send_queue, packet);
838 this->logger->log(this->logger, CONTROL, "sending keep alive");
839 diff = 0;
840 }
841 job = send_keepalive_job_create(this->ike_sa_id);
842 charon->event_queue->add_relative(charon->event_queue, (job_t*)job,
843 (interval - diff) * 1000);
844 }
845
846 /**
847 * Implementation of ike_sa_t.get_state.
848 */
849 static ike_sa_state_t get_state(private_ike_sa_t *this)
850 {
851 return this->state;
852 }
853
854 /**
855 * Implementation of ike_sa_t.set_state.
856 */
857 static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
858 {
859 this->logger->log(this->logger, CONTROL, "state change: %s => %s",
860 mapping_find(ike_sa_state_m, this->state),
861 mapping_find(ike_sa_state_m, state));
862 if (state == SA_ESTABLISHED)
863 {
864 host_t *my_host, *other_host;
865 identification_t *my_id, *other_id;
866 my_host = this->connection->get_my_host(this->connection);
867 other_host = this->connection->get_other_host(this->connection);
868 my_id = this->policy->get_my_id(this->policy);
869 other_id = this->policy->get_other_id(this->policy);
870 this->logger->log(this->logger, AUDIT, "IKE_SA established: %s[%s]...%s[%s]",
871 my_host->get_address(my_host),
872 my_id->get_string(my_id),
873 other_host->get_address(other_host),
874 other_id->get_string(other_id));
875
876 send_dpd(this);
877 }
878 this->state = state;
879 }
880
881 /**
882 * Implementation of protected_ike_sa_t.get_connection.
883 */
884 static connection_t *get_connection(private_ike_sa_t *this)
885 {
886 return this->connection;
887 }
888
889 /**
890 * Implementation of protected_ike_sa_t.set_connection.
891 */
892 static void set_connection(private_ike_sa_t *this,connection_t * connection)
893 {
894 this->connection = connection;
895 }
896
897 /**
898 * Implementation of protected_ike_sa_t.get_policy.
899 */
900 static policy_t *get_policy(private_ike_sa_t *this)
901 {
902 return this->policy;
903 }
904
905 /**
906 * Implementation of protected_ike_sa_t.set_policy.
907 */
908 static void set_policy(private_ike_sa_t *this,policy_t * policy)
909 {
910 this->policy = policy;
911 }
912
913 /**
914 * Implementation of protected_ike_sa_t.get_prf.
915 */
916 static prf_t *get_prf(private_ike_sa_t *this)
917 {
918 return this->prf;
919 }
920
921 /**
922 * Implementation of protected_ike_sa_t.get_prf.
923 */
924 static prf_t *get_child_prf(private_ike_sa_t *this)
925 {
926 return this->child_prf;
927 }
928
929 /**
930 * Implementation of protected_ike_sa_t.get_prf_auth_i.
931 */
932 static prf_t *get_prf_auth_i(private_ike_sa_t *this)
933 {
934 return this->prf_auth_i;
935 }
936
937 /**
938 * Implementation of protected_ike_sa_t.get_prf_auth_r.
939 */
940 static prf_t *get_prf_auth_r(private_ike_sa_t *this)
941 {
942 return this->prf_auth_r;
943 }
944 /**
945 * Implementation of ike_sa_t.get_id.
946 */
947 static ike_sa_id_t* get_id(private_ike_sa_t *this)
948 {
949 return this->ike_sa_id;
950 }
951
952 /**
953 * Implementation of protected_ike_sa_t.build_transforms.
954 */
955 static status_t build_transforms(private_ike_sa_t *this, proposal_t *proposal,
956 diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r,
957 bool initiator)
958 {
959 chunk_t nonces, nonces_spis, skeyseed, key, secret;
960 u_int64_t spi_i, spi_r;
961 prf_plus_t *prf_plus;
962 algorithm_t *algo;
963 size_t key_size;
964 crypter_t *crypter_i, *crypter_r;
965 signer_t *signer_i, *signer_r;
966
967 /* Build the PRF+ instance for deriving keys */
968 if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo))
969 {
970 this->logger->log(this->logger, ERROR, "no PSEUDO_RANDOM_FUNCTION selected!");
971 return FAILED;
972 }
973 this->prf = prf_create(algo->algorithm);
974 if (this->prf == NULL)
975 {
976 this->logger->log(this->logger, ERROR, "PSEUDO_RANDOM_FUNCTION %s not supported!",
977 mapping_find(pseudo_random_function_m, algo->algorithm));
978 return FAILED;
979 }
980
981 /* nonces = nonce_i | nonce_r */
982 nonces = chunk_alloc(nonce_i.len + nonce_r.len);
983 memcpy(nonces.ptr, nonce_i.ptr, nonce_i.len);
984 memcpy(nonces.ptr + nonce_i.len, nonce_r.ptr, nonce_r.len);
985
986 /* prf_seed = nonce_i | nonce_r | spi_i | spi_r */
987 nonces_spis = chunk_alloc(nonces.len + 16);
988 memcpy(nonces_spis.ptr, nonces.ptr, nonces.len);
989 spi_i = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
990 spi_r = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
991 memcpy(nonces_spis.ptr + nonces.len, &spi_i, 8);
992 memcpy(nonces_spis.ptr + nonces.len + 8, &spi_r, 8);
993
994 /* SKEYSEED = prf(Ni | Nr, g^ir) */
995 dh->get_shared_secret(dh, &secret);
996 this->logger->log_chunk(this->logger, PRIVATE, "shared Diffie Hellman secret", secret);
997 this->prf->set_key(this->prf, nonces);
998 this->prf->allocate_bytes(this->prf, secret, &skeyseed);
999 this->logger->log_chunk(this->logger, PRIVATE|LEVEL1, "SKEYSEED", skeyseed);
1000 chunk_free(&secret);
1001
1002 /* prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr )
1003 * = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr
1004 */
1005 this->prf->set_key(this->prf, skeyseed);
1006 prf_plus = prf_plus_create(this->prf, nonces_spis);
1007
1008 /* clean up unused stuff */
1009 chunk_free(&nonces);
1010 chunk_free(&nonces_spis);
1011 chunk_free(&skeyseed);
1012
1013 /* SK_d used for prf+ to derive keys for child SAs */
1014 this->child_prf = prf_create(algo->algorithm);
1015 key_size = this->child_prf->get_key_size(this->child_prf);
1016 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1017 this->logger->log_chunk(this->logger, PRIVATE, "Sk_d secret", key);
1018 this->child_prf->set_key(this->child_prf, key);
1019 chunk_free(&key);
1020
1021 /* SK_ai/SK_ar used for integrity protection */
1022 if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &algo))
1023 {
1024 this->logger->log(this->logger, ERROR, "no INTEGRITY_ALGORITHM selected?!");
1025 return FAILED;
1026 }
1027
1028 signer_i = signer_create(algo->algorithm);
1029 signer_r = signer_create(algo->algorithm);
1030 if (signer_i == NULL || signer_r == NULL)
1031 {
1032 this->logger->log(this->logger, ERROR, "INTEGRITY_ALGORITHM %s not supported!",
1033 mapping_find(integrity_algorithm_m,algo->algorithm));
1034 return FAILED;
1035 }
1036 key_size = signer_i->get_key_size(signer_i);
1037
1038 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1039 this->logger->log_chunk(this->logger, CONTROL|LEVEL1, "Sk_ai secret", key);
1040 signer_i->set_key(signer_i, key);
1041 chunk_free(&key);
1042
1043 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1044 this->logger->log_chunk(this->logger, CONTROL|LEVEL1, "Sk_ar secret", key);
1045 signer_r->set_key(signer_r, key);
1046 chunk_free(&key);
1047
1048 if (initiator)
1049 {
1050 this->signer_in = signer_r;
1051 this->signer_out = signer_i;
1052 }
1053 else
1054 {
1055 this->signer_in = signer_i;
1056 this->signer_out = signer_r;
1057 }
1058
1059 /* SK_ei/SK_er used for encryption */
1060 if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &algo))
1061 {
1062 this->logger->log(this->logger, ERROR, "no ENCRYPTION_ALGORITHM selected!");
1063 return FAILED;
1064 }
1065 crypter_i = crypter_create(algo->algorithm, algo->key_size / 8);
1066 crypter_r = crypter_create(algo->algorithm, algo->key_size / 8);
1067 if (crypter_i == NULL || crypter_r == NULL)
1068 {
1069 this->logger->log(this->logger, ERROR,
1070 "ENCRYPTION_ALGORITHM %s (key size %d) not supported!",
1071 mapping_find(encryption_algorithm_m, algo->algorithm),
1072 algo->key_size);
1073 return FAILED;
1074 }
1075 key_size = crypter_i->get_key_size(crypter_i);
1076
1077 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1078 this->logger->log_chunk(this->logger, PRIVATE, "Sk_ei secret", key);
1079 crypter_i->set_key(crypter_i, key);
1080 chunk_free(&key);
1081
1082 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1083 this->logger->log_chunk(this->logger, PRIVATE, "Sk_er secret", key);
1084 crypter_r->set_key(crypter_r, key);
1085 chunk_free(&key);
1086
1087 if (initiator)
1088 {
1089 this->crypter_in = crypter_r;
1090 this->crypter_out = crypter_i;
1091 }
1092 else
1093 {
1094 this->crypter_in = crypter_i;
1095 this->crypter_out = crypter_r;
1096 }
1097
1098 /* SK_pi/SK_pr used for authentication */
1099 proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo);
1100 this->prf_auth_i = prf_create(algo->algorithm);
1101 this->prf_auth_r = prf_create(algo->algorithm);
1102
1103 key_size = this->prf_auth_i->get_key_size(this->prf_auth_i);
1104 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1105 this->logger->log_chunk(this->logger, PRIVATE, "Sk_pi secret", key);
1106 this->prf_auth_i->set_key(this->prf_auth_i, key);
1107 chunk_free(&key);
1108
1109 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1110 this->logger->log_chunk(this->logger, PRIVATE, "Sk_pr secret", key);
1111 this->prf_auth_r->set_key(this->prf_auth_r, key);
1112 chunk_free(&key);
1113
1114 /* all done, prf_plus not needed anymore */
1115 prf_plus->destroy(prf_plus);
1116
1117 return SUCCESS;
1118 }
1119
1120 /**
1121 * Implementation of protected_ike_sa_t.add_child_sa.
1122 */
1123 static void add_child_sa(private_ike_sa_t *this, child_sa_t *child_sa)
1124 {
1125 this->child_sas->insert_last(this->child_sas, child_sa);
1126 }
1127
1128 /**
1129 * Implementation of protected_ike_sa_t.get_child_sa.
1130 */
1131 static child_sa_t* get_child_sa(private_ike_sa_t *this, protocol_id_t protocol,
1132 u_int32_t spi, bool inbound)
1133 {
1134 iterator_t *iterator;
1135 child_sa_t *current, *found = NULL;
1136
1137 iterator = this->child_sas->create_iterator(this->child_sas, FALSE);
1138 while (iterator->has_next(iterator))
1139 {
1140 iterator->current(iterator, (void**)&current);
1141 if (current->get_spi(current, inbound) == spi &&
1142 current->get_protocol(current) == protocol)
1143 {
1144 found = current;
1145 }
1146 }
1147 iterator->destroy(iterator);
1148 return found;
1149 }
1150
1151 /**
1152 * Implementation of ike_sa_t.rekey_child_sa.
1153 */
1154 static status_t rekey_child_sa(private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi)
1155 {
1156 create_child_sa_t *rekey;
1157 child_sa_t *child_sa;
1158
1159 child_sa = get_child_sa(this, protocol, spi, TRUE);
1160 if (child_sa == NULL)
1161 {
1162 return NOT_FOUND;
1163 }
1164
1165 rekey = create_child_sa_create(&this->public, this->message_id_out++);
1166 rekey->rekeys_child(rekey, child_sa);
1167 return queue_transaction(this, (transaction_t*)rekey, FALSE);
1168 }
1169
1170 /**
1171 * Implementation of ike_sa_t.delete_child_sa.
1172 */
1173 static status_t delete_child_sa(private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi)
1174 {
1175 delete_child_sa_t *del;
1176 child_sa_t *child_sa;
1177
1178 child_sa = get_child_sa(this, protocol, spi, TRUE);
1179 if (child_sa == NULL)
1180 {
1181 return NOT_FOUND;
1182 }
1183
1184 del = delete_child_sa_create(&this->public, this->message_id_out++);
1185 del->set_child_sa(del, child_sa);
1186 return queue_transaction(this, (transaction_t*)del, FALSE);
1187 }
1188
1189 /**
1190 * Implementation of protected_ike_sa_t.destroy_child_sa.
1191 */
1192 static status_t destroy_child_sa(private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi)
1193 {
1194 iterator_t *iterator;
1195 child_sa_t *child_sa;
1196 status_t status = NOT_FOUND;
1197
1198 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
1199 while (iterator->iterate(iterator, (void**)&child_sa))
1200 {
1201 if (child_sa->get_protocol(child_sa) == protocol &&
1202 child_sa->get_spi(child_sa, TRUE) == spi)
1203 {
1204 child_sa->destroy(child_sa);
1205 iterator->remove(iterator);
1206 status = SUCCESS;
1207 break;
1208 }
1209 }
1210 iterator->destroy(iterator);
1211 return status;
1212 }
1213
1214
1215 /**
1216 * Implementation of protected_ike_sa_t.log_status.
1217 */
1218 static void log_status(private_ike_sa_t *this, logger_t *logger, char *name)
1219 {
1220 iterator_t *iterator;
1221 child_sa_t *child_sa;
1222 host_t *my_host, *other_host;
1223 identification_t *my_id = NULL, *other_id = NULL;
1224
1225 /* only log if name == NULL or name == connection_name */
1226 if (name)
1227 {
1228 if (streq(this->connection->get_name(this->connection), name))
1229 {
1230 return;
1231 }
1232 }
1233 my_host = this->connection->get_my_host(this->connection);
1234 other_host = this->connection->get_other_host(this->connection);
1235
1236 /* use policy information, if available */
1237 if (this->policy)
1238 {
1239 my_id = this->policy->get_my_id(this->policy);
1240 other_id = this->policy->get_other_id(this->policy);
1241 name = this->policy->get_name(this->policy);
1242 }
1243 else
1244 {
1245 name = this->connection->get_name(this->connection);
1246 }
1247
1248 if (logger == NULL)
1249 {
1250 logger = this->logger;
1251 }
1252 logger->log(logger, CONTROL|LEVEL1, " \"%s\": IKE_SA in state %s, SPIs: 0x%.16llx 0x%.16llx",
1253 name,
1254 mapping_find(ike_sa_state_m, this->state),
1255 this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
1256 this->ike_sa_id->get_responder_spi(this->ike_sa_id));
1257 logger->log(logger, CONTROL, " \"%s\": %s[%s]...%s[%s]",
1258 name,
1259 my_host->get_address(my_host),
1260 my_id ? my_id->get_string(my_id) : "(unknown)",
1261 other_host->get_address(other_host),
1262 other_id ? other_id->get_string(other_id) : "(unknown)");
1263
1264 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
1265 while (iterator->has_next(iterator))
1266 {
1267 iterator->current(iterator, (void**)&child_sa);
1268 child_sa->log_status(child_sa, logger, name);
1269 }
1270 iterator->destroy(iterator);
1271 }
1272
1273 /**
1274 * Implementation of public_ike_sa_t.delete.
1275 */
1276 static status_t delete_(private_ike_sa_t *this)
1277 {
1278 delete_ike_sa_t *delete_ike_sa;
1279 delete_ike_sa = delete_ike_sa_create(&this->public, this->message_id_out++);
1280
1281 return queue_transaction(this, (transaction_t*)delete_ike_sa, FALSE);
1282 }
1283
1284 /**
1285 * Implementation of ike_sa_t.is_natt_enabled.
1286 */
1287 static bool is_natt_enabled (private_ike_sa_t *this)
1288 {
1289 return this->nat_here || this->nat_there;
1290 }
1291
1292 /**
1293 * Implementation of protected_ike_sa_t.enable_natt.
1294 */
1295 static void enable_natt (private_ike_sa_t *this, bool local)
1296 {
1297 if (local)
1298 {
1299 this->logger->log(this->logger, CONTROL,
1300 "local host is behind NAT, using NAT-T, scheduled keep alives");
1301 this->nat_here = TRUE;
1302 send_keepalive(this);
1303 }
1304 else
1305 {
1306 this->logger->log(this->logger, CONTROL,
1307 "remote host is behind NAT, using NAT-T");
1308 this->nat_there = TRUE;
1309 }
1310 }
1311
1312 /**
1313 * Implementation of protected_ike_sa_t.destroy.
1314 */
1315 static void destroy(private_ike_sa_t *this)
1316 {
1317 child_sa_t *child_sa;
1318 transaction_t *transaction;
1319
1320 this->logger->log(this->logger, CONTROL|LEVEL2, "going to destroy IKE SA %llu:%llu, role %s",
1321 this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
1322 this->ike_sa_id->get_responder_spi(this->ike_sa_id),
1323 this->ike_sa_id->is_initiator(this->ike_sa_id) ? "initiator" : "responder");
1324
1325 if (this->state == SA_ESTABLISHED)
1326 {
1327 this->logger->log(this->logger, ERROR,
1328 "destroying an established IKE SA without knowledge from remote peer!");
1329 }
1330
1331 while (this->child_sas->remove_last(this->child_sas, (void**)&child_sa) == SUCCESS)
1332 {
1333 child_sa->destroy(child_sa);
1334 }
1335 this->child_sas->destroy(this->child_sas);
1336
1337 while (this->transaction_queue->remove_last(this->transaction_queue, (void**)&transaction) == SUCCESS)
1338 {
1339 transaction->destroy(transaction);
1340 }
1341 this->transaction_queue->destroy(this->transaction_queue);
1342 if (this->transaction_in)
1343 {
1344 this->transaction_in->destroy(this->transaction_in);
1345 }
1346 if (this->transaction_in_next)
1347 {
1348 this->transaction_in_next->destroy(this->transaction_in_next);
1349 }
1350 if (this->transaction_out)
1351 {
1352 this->transaction_out->destroy(this->transaction_out);
1353 }
1354 if (this->crypter_in)
1355 {
1356 this->crypter_in->destroy(this->crypter_in);
1357 }
1358 if (this->crypter_out)
1359 {
1360 this->crypter_out->destroy(this->crypter_out);
1361 }
1362 if (this->signer_in)
1363 {
1364 this->signer_in->destroy(this->signer_in);
1365 }
1366 if (this->signer_out)
1367 {
1368 this->signer_out->destroy(this->signer_out);
1369 }
1370 if (this->prf)
1371 {
1372 this->prf->destroy(this->prf);
1373 }
1374 if (this->child_prf)
1375 {
1376 this->child_prf->destroy(this->child_prf);
1377 }
1378 if (this->prf_auth_i)
1379 {
1380 this->prf_auth_i->destroy(this->prf_auth_i);
1381 }
1382 if (this->prf_auth_r)
1383 {
1384 this->prf_auth_r->destroy(this->prf_auth_r);
1385 }
1386 if (this->connection)
1387 {
1388 host_t *my_host, *other_host;
1389 identification_t *my_id = NULL, *other_id = NULL;
1390 my_host = this->connection->get_my_host(this->connection);
1391 other_host = this->connection->get_other_host(this->connection);
1392 if (this->policy)
1393 {
1394 my_id = this->policy->get_my_id(this->policy);
1395 other_id = this->policy->get_other_id(this->policy);
1396 }
1397
1398 this->logger->log(this->logger, AUDIT, "IKE_SA deleted between %s[%s]...%s[%s]",
1399 my_host->get_address(my_host),
1400 my_id ? my_id->get_string(my_id) : "(unknown)",
1401 other_host->get_address(other_host),
1402 other_id ? other_id->get_string(other_id) : "(unknown)");
1403 this->connection->destroy(this->connection);
1404 }
1405 if (this->policy)
1406 {
1407 this->policy->destroy(this->policy);
1408 }
1409 this->ike_sa_id->destroy(this->ike_sa_id);
1410 free(this);
1411 }
1412
1413 /*
1414 * Described in header.
1415 */
1416 ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
1417 {
1418 private_ike_sa_t *this = malloc_thing(private_ike_sa_t);
1419
1420 /* Public functions */
1421 this->public.get_state = (ike_sa_state_t(*)(ike_sa_t*)) get_state;
1422 this->public.set_state = (void(*)(ike_sa_t*,ike_sa_state_t)) set_state;
1423 this->public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message;
1424 this->public.initiate = (status_t(*)(ike_sa_t*,connection_t*)) initiate;
1425 this->public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id;
1426 this->public.get_connection = (connection_t*(*)(ike_sa_t*)) get_connection;
1427 this->public.retransmit_request = (status_t (*) (ike_sa_t *, u_int32_t)) retransmit_request;
1428 this->public.log_status = (void (*) (ike_sa_t*,logger_t*,char*))log_status;
1429 this->public.delete = (status_t(*)(ike_sa_t*))delete_;
1430 this->public.destroy = (void(*)(ike_sa_t*))destroy;
1431 this->public.send_dpd = (status_t (*)(ike_sa_t*)) send_dpd;
1432 this->public.send_keepalive = (void (*)(ike_sa_t*)) send_keepalive;
1433 this->public.get_prf = (prf_t *(*) (ike_sa_t *)) get_prf;
1434 this->public.get_child_prf = (prf_t *(*) (ike_sa_t *)) get_child_prf;
1435 this->public.get_prf_auth_i = (prf_t *(*) (ike_sa_t *)) get_prf_auth_i;
1436 this->public.get_prf_auth_r = (prf_t *(*) (ike_sa_t *)) get_prf_auth_r;
1437 this->public.set_connection = (void (*) (ike_sa_t *,connection_t *)) set_connection;
1438 this->public.get_connection = (connection_t *(*) (ike_sa_t *)) get_connection;
1439 this->public.set_policy = (void (*) (ike_sa_t *,policy_t *)) set_policy;
1440 this->public.get_policy = (policy_t *(*) (ike_sa_t *)) get_policy;
1441 this->public.build_transforms = (status_t (*) (ike_sa_t *,proposal_t*,diffie_hellman_t*,chunk_t,chunk_t,bool)) build_transforms;
1442 this->public.add_child_sa = (void (*) (ike_sa_t*,child_sa_t*)) add_child_sa;
1443 this->public.get_child_sa = (child_sa_t* (*)(ike_sa_t*,protocol_id_t,u_int32_t,bool)) get_child_sa;
1444 this->public.rekey_child_sa = (status_t(*)(ike_sa_t*,protocol_id_t,u_int32_t)) rekey_child_sa;
1445 this->public.delete_child_sa = (status_t(*)(ike_sa_t*,protocol_id_t,u_int32_t)) delete_child_sa;
1446 this->public.destroy_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t))destroy_child_sa;
1447 this->public.enable_natt = (void(*)(ike_sa_t*, bool)) enable_natt;
1448 this->public.is_natt_enabled = (bool(*)(ike_sa_t*)) is_natt_enabled;
1449
1450 /* initialize private fields */
1451 this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
1452 this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
1453 this->child_sas = linked_list_create();
1454 this->crypter_in = NULL;
1455 this->crypter_out = NULL;
1456 this->signer_in = NULL;
1457 this->signer_out = NULL;
1458 this->prf = NULL;
1459 this->prf_auth_i = NULL;
1460 this->prf_auth_r = NULL;
1461 this->child_prf = NULL;
1462 this->connection = NULL;
1463 this->policy = NULL;
1464 this->nat_here = FALSE;
1465 this->nat_there = FALSE;
1466 this->transaction_queue = linked_list_create();
1467 this->transaction_in = NULL;
1468 this->transaction_in_next = NULL;
1469 this->transaction_out = NULL;
1470 this->state = SA_CREATED;
1471 this->message_id_out = 0;
1472 this->time_inbound = 0;
1473 this->time_outbound = 0;
1474
1475 return &this->public;
1476 }