]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/charon/sa/ike_sa.c
added possibility to route CHILD_SAs, without to set them up
[thirdparty/strongswan.git] / src / charon / sa / ike_sa.c
CommitLineData
7ba38761
JH
1/**
2 * @file ike_sa.c
79538669 3 *
df3c59d0 4 * @brief Implementation of ike_sa_t.
79538669 5 *
7ba38761
JH
6 */
7
8/*
1396815a 9 * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
c71d53ba
MW
10 * Copyright (C) 2005-2006 Martin Willi
11 * Copyright (C) 2005 Jan Hutter
7ba38761
JH
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 */
1396815a
MW
24
25#include <sys/time.h>
5113680f 26#include <string.h>
7ba38761 27
88878242
MW
28#include "ike_sa.h"
29
021c2322 30#include <types.h>
0e96f7d8 31#include <daemon.h>
021c2322 32#include <definitions.h>
021c2322
MW
33#include <utils/linked_list.h>
34#include <utils/logger_manager.h>
68621281
MW
35#include <crypto/diffie_hellman.h>
36#include <crypto/prf_plus.h>
37#include <crypto/crypters/crypter.h>
1396815a 38#include <crypto/hashers/hasher.h>
4a962238
MW
39#include <encoding/payloads/sa_payload.h>
40#include <encoding/payloads/nonce_payload.h>
41#include <encoding/payloads/ke_payload.h>
e9c0ca15 42#include <encoding/payloads/delete_payload.h>
4a962238
MW
43#include <encoding/payloads/transform_substructure.h>
44#include <encoding/payloads/transform_attribute.h>
8d77edde 45#include <encoding/payloads/ts_payload.h>
3dd3c5f3
MW
46#include <sa/transactions/transaction.h>
47#include <sa/transactions/ike_sa_init.h>
48#include <sa/transactions/delete_ike_sa.h>
698d7749
MW
49#include <sa/transactions/create_child_sa.h>
50#include <sa/transactions/delete_child_sa.h>
3dd3c5f3 51#include <sa/transactions/dead_peer_detection.h>
0df63d6b 52#include <queues/jobs/retransmit_request_job.h>
e314700c 53#include <queues/jobs/delete_established_ike_sa_job.h>
4a5bba25 54#include <queues/jobs/delete_half_open_ike_sa_job.h>
3dd3c5f3
MW
55#include <queues/jobs/send_dpd_job.h>
56#include <queues/jobs/send_keepalive_job.h>
7ba38761
JH
57
58
3dd3c5f3
MW
59/**
60 * String mappings for ike_sa_state_t.
61 */
62mapping_t ike_sa_state_m[] = {
bcb95ced
MW
63 {IKE_CREATED, "CREATED"},
64 {IKE_CONNECTING, "CONNECTING"},
65 {IKE_ESTABLISHED, "ESTABLISHED"},
66 {IKE_DELETING, "DELETING"},
3dd3c5f3
MW
67 {MAPPING_END, NULL}
68};
501a41b9 69
7ba38761 70
aad398a7
JH
71typedef struct private_ike_sa_t private_ike_sa_t;
72
73/**
74 * Private data of an ike_sa_t object.
75 */
76struct private_ike_sa_t {
77
78 /**
3dd3c5f3 79 * Public members
2f89902d 80 */
3dd3c5f3 81 ike_sa_t public;
2f89902d 82
aad398a7 83 /**
a374d1ee 84 * Identifier for the current IKE_SA.
aad398a7
JH
85 */
86 ike_sa_id_t *ike_sa_id;
8d77edde 87
aad398a7 88 /**
8dfbe71b 89 * Current state of the IKE_SA
aad398a7 90 */
8dfbe71b 91 ike_sa_state_t state;
a9428251
JH
92
93 /**
8dfbe71b 94 * Name of the connection used by this IKE_SA
a9428251 95 */
8dfbe71b
MW
96 char *name;
97
98 /**
99 * Address of local host
100 */
101 host_t *my_host;
102
103 /**
104 * Address of remote host
105 */
106 host_t *other_host;
107
108 /**
109 * Identification used for us
110 */
111 identification_t *my_id;
a9428251
JH
112
113 /**
8dfbe71b 114 * Identification used for other
a9428251 115 */
8dfbe71b 116 identification_t *other_id;
a374d1ee 117
aad398a7 118 /**
8dfbe71b 119 * Linked List containing the child sa's of the current IKE_SA.
aad398a7 120 */
8dfbe71b 121 linked_list_t *child_sas;
aad398a7
JH
122
123 /**
3dd3c5f3 124 * crypter for inbound traffic
aad398a7 125 */
3dd3c5f3 126 crypter_t *crypter_in;
aad398a7
JH
127
128 /**
3dd3c5f3 129 * crypter for outbound traffic
aad398a7 130 */
3dd3c5f3 131 crypter_t *crypter_out;
aad398a7
JH
132
133 /**
3dd3c5f3 134 * Signer for inbound traffic
aad398a7 135 */
3dd3c5f3 136 signer_t *signer_in;
aad398a7
JH
137
138 /**
3dd3c5f3 139 * Signer for outbound traffic
aad398a7 140 */
3dd3c5f3 141 signer_t *signer_out;
aad398a7
JH
142
143 /**
ce461bbd 144 * Multi purpose prf, set key, use it, forget it
aad398a7
JH
145 */
146 prf_t *prf;
147
5b97779f
MW
148 /**
149 * Prf function for derivating keymat child SAs
5b97779f
MW
150 */
151 prf_t *child_prf;
152
aad398a7 153 /**
ce461bbd 154 * PRF, with key set to pi_key, used for authentication
aad398a7 155 */
ce461bbd 156 prf_t *prf_auth_i;
aad398a7 157
ce461bbd
MW
158 /**
159 * PRF, with key set to pr_key, used for authentication
160 */
161 prf_t *prf_auth_r;
0df63d6b 162
aad398a7 163 /**
a374d1ee 164 * A logger for this IKE_SA.
aad398a7
JH
165 */
166 logger_t *logger;
1396815a
MW
167
168 /**
169 * NAT hasher.
170 */
171 hasher_t *nat_hasher;
172
173 /**
174 * NAT status of local host.
175 */
176 bool nat_here;
177
178 /**
179 * NAT status of remote host.
180 */
181 bool nat_there;
3dd3c5f3
MW
182
183 /**
184 * message ID for next outgoung request
185 */
186 u_int32_t message_id_out;
1396815a
MW
187
188 /**
2f89902d 189 * Timestamp of last IKE message received on this SA
1396815a 190 */
3dd3c5f3 191 time_t time_inbound;
2f89902d
MW
192
193 /**
194 * Timestamp of last IKE message sent on this SA
195 */
3dd3c5f3
MW
196 time_t time_outbound;
197
198 /**
199 * List of queued transactions to process
200 */
201 linked_list_t *transaction_queue;
202
203 /**
204 * Transaction currently initiated
205 * (only one supported yet, window size = 1)
206 */
207 transaction_t *transaction_out;
208
209 /**
210 * last transaction initiated by peer processed.
211 * (only one supported yet, window size = 1)
212 * Stored for retransmission.
1396815a 213 */
3dd3c5f3
MW
214 transaction_t *transaction_in;
215
216 /**
217 * Next incoming transaction expected. Used to
218 * do multi transaction operations.
219 */
220 transaction_t *transaction_in_next;
aad398a7
JH
221};
222
0b2abb8c 223/**
3dd3c5f3 224 * get the time of the latest traffic processed by the kernel
0b2abb8c 225 */
8dfbe71b 226static time_t get_kernel_time(private_ike_sa_t* this, bool inbound)
3a8f9f44 227{
3dd3c5f3
MW
228 iterator_t *iterator;
229 child_sa_t *child_sa;
230 time_t latest = 0, use_time;
16b9a73c 231
3dd3c5f3
MW
232 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
233 while (iterator->iterate(iterator, (void**)&child_sa))
234 {
235 if (child_sa->get_use_time(child_sa, inbound, &use_time) == SUCCESS)
236 {
237 latest = max(latest, use_time);
238 }
239 }
240 iterator->destroy(iterator);
5534ee84 241
3dd3c5f3 242 return latest;
a9428251
JH
243}
244
aad398a7 245/**
3dd3c5f3 246 * get the time of the latest received traffice
aad398a7 247 */
3dd3c5f3 248static time_t get_time_inbound(private_ike_sa_t *this)
aad398a7 249{
8dfbe71b 250 return max(this->time_inbound, get_kernel_time(this, TRUE));
aad398a7
JH
251}
252
0fdc3c7f 253/**
3dd3c5f3 254 * get the time of the latest sent traffic
0fdc3c7f 255 */
3dd3c5f3 256static time_t get_time_outbound(private_ike_sa_t *this)
0fdc3c7f 257{
8dfbe71b 258 return max(this->time_outbound, get_kernel_time(this, FALSE));
0fdc3c7f
JH
259}
260
8dfbe71b
MW
261/**
262 * Implementation of ike_sa_t.get_name.
263 */
264static char *get_name(private_ike_sa_t *this)
265{
266 return this->name;
267}
268
269/**
270 * Implementation of ike_sa_t.set_name.
271 */
272static void set_name(private_ike_sa_t *this, char* name)
273{
274 free(this->name);
275 this->name = strdup(name);
276}
277
278/**
279 * Implementation of ike_sa_t.get_my_host.
280 */
281static host_t *get_my_host(private_ike_sa_t *this)
282{
283 return this->my_host;
284}
285
286/**
287 * Implementation of ike_sa_t.get_other_host.
288 */
289static host_t *get_other_host(private_ike_sa_t *this)
290{
291 return this->other_host;
292}
5b97779f 293
0fdc3c7f 294/**
3dd3c5f3 295 * Update connection host, as addresses may change (NAT)
0fdc3c7f 296 */
3dd3c5f3 297static void update_hosts(private_ike_sa_t *this, host_t *me, host_t *other)
0fdc3c7f 298{
3dd3c5f3
MW
299 /*
300 * Quoting RFC 4306:
301 *
302 * 2.11. Address and Port Agility
303 *
304 * IKE runs over UDP ports 500 and 4500, and implicitly sets up ESP and
305 * AH associations for the same IP addresses it runs over. The IP
306 * addresses and ports in the outer header are, however, not themselves
307 * cryptographically protected, and IKE is designed to work even through
308 * Network Address Translation (NAT) boxes. An implementation MUST
309 * accept incoming requests even if the source port is not 500 or 4500,
310 * and MUST respond to the address and port from which the request was
311 * received. It MUST specify the address and port at which the request
312 * was received as the source address and port in the response. IKE
313 * functions identically over IPv4 or IPv6.
314 *
315 * [...]
316 *
317 * There are cases where a NAT box decides to remove mappings that
318 * are still alive (for example, the keepalive interval is too long,
319 * or the NAT box is rebooted). To recover in these cases, hosts
320 * that are not behind a NAT SHOULD send all packets (including
321 * retransmission packets) to the IP address and port from the last
322 * valid authenticated packet from the other end (i.e., dynamically
323 * update the address). A host behind a NAT SHOULD NOT do this
324 * because it opens a DoS attack possibility. Any authenticated IKE
325 * packet or any authenticated UDP-encapsulated ESP packet can be
326 * used to detect that the IP address or the port has changed.
327 */
3dd3c5f3
MW
328 iterator_t *iterator = NULL;
329 child_sa_t *child_sa = NULL;
8dfbe71b
MW
330 host_diff_t my_diff, other_diff;
331
45f76a7d
MW
332 if (this->my_host->is_anyaddr(this->my_host) ||
333 this->other_host->is_anyaddr(this->other_host))
8dfbe71b
MW
334 {
335 /* on first received message */
45f76a7d 336 this->my_host->destroy(this->my_host);
8dfbe71b 337 this->my_host = me->clone(me);
45f76a7d 338 this->other_host->destroy(this->other_host);
8dfbe71b
MW
339 this->other_host = other->clone(other);
340 return;
341 }
342
343 my_diff = me->get_differences(me, this->my_host);
344 other_diff = other->get_differences(other, this->other_host);
345
346 if (!my_diff && !other_diff)
3dd3c5f3
MW
347 {
348 return;
349 }
350
8dfbe71b 351 if (my_diff)
3dd3c5f3 352 {
8dfbe71b
MW
353 this->my_host->destroy(this->my_host);
354 this->my_host = me->clone(me);
3dd3c5f3
MW
355 }
356
357 if (!this->nat_here)
358 {
359 /* update without restrictions if we are not NATted */
8dfbe71b 360 if (other_diff)
3dd3c5f3 361 {
8dfbe71b
MW
362 this->other_host->destroy(this->other_host);
363 this->other_host = other->clone(other);
3dd3c5f3
MW
364 }
365 }
366 else
367 {
368 /* if we are natted, only port may change */
8dfbe71b 369 if (other_diff & HOST_DIFF_ADDR)
3dd3c5f3
MW
370 {
371 return;
372 }
8dfbe71b 373 else if (other_diff & HOST_DIFF_PORT)
3dd3c5f3 374 {
8dfbe71b 375 this->other_host->set_port(this->other_host, other->get_port(other));
3dd3c5f3
MW
376 }
377 }
378 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
379 while (iterator->iterate(iterator, (void**)&child_sa))
380 {
8dfbe71b
MW
381 child_sa->update_hosts(child_sa, this->my_host, this->other_host,
382 my_diff, other_diff);
3dd3c5f3
MW
383 /* TODO: what to do if update fails? Delete CHILD_SA? */
384 }
385 iterator->destroy(iterator);
8d77edde
MW
386}
387
388/**
3dd3c5f3 389 * send a request and schedule retransmission
8d77edde 390 */
3dd3c5f3 391static status_t transmit_request(private_ike_sa_t *this)
8d77edde 392{
3dd3c5f3
MW
393 message_t *request;
394 packet_t *packet;
395 status_t status;
396 retransmit_request_job_t *job;
397 u_int32_t transmitted;
398 u_int32_t timeout;
399 transaction_t *transaction = this->transaction_out;
400 u_int32_t message_id = transaction->get_message_id(transaction);
401
402 transmitted = transaction->requested(transaction);
403 timeout = charon->configuration->get_retransmit_timeout(charon->configuration,
404 transmitted);
405 if (timeout == 0)
406 {
407 this->logger->log(this->logger, ERROR,
408 "giving up after %d retransmits, deleting IKE_SA",
409 transmitted - 1);
410 return DESTROY_ME;
411 }
412
413 status = transaction->get_request(transaction, &request);
414 if (status != SUCCESS)
415 {
416 return status;
417 }
418 /* if we retransmit, the request is already generated */
419 if (transmitted == 0)
420 {
421 status = request->generate(request, this->crypter_out, this->signer_out, &packet);
422 if (status != SUCCESS)
423 {
92ee45a0
MW
424 this->logger->log(this->logger, ERROR,
425 "request generation failed. transaction discarded");
3dd3c5f3
MW
426 return FAILED;
427 }
428 }
429 else
430 {
431 this->logger->log(this->logger, CONTROL,
432 "sending retransmit %d for %s request with message ID %d",
433 transmitted,
434 mapping_find(exchange_type_m, request->get_exchange_type(request)),
435 message_id);
436 packet = request->get_packet(request);
437 }
438 /* finally send */
439 charon->send_queue->add(charon->send_queue, packet);
440 this->time_outbound = time(NULL);
441
442 /* schedule retransmission job */
443 job = retransmit_request_job_create(message_id, this->ike_sa_id);
444 charon->event_queue->add_relative(charon->event_queue, (job_t*)job, timeout);
445 return SUCCESS;
8d77edde
MW
446}
447
448/**
3dd3c5f3 449 * Implementation of ike_sa.retransmit_request.
8d77edde 450 */
3dd3c5f3 451static status_t retransmit_request(private_ike_sa_t *this, u_int32_t message_id)
8d77edde 452{
3dd3c5f3
MW
453 if (this->transaction_out == NULL ||
454 this->transaction_out->get_message_id(this->transaction_out) != message_id)
455 {
456 /* no retransmit necessary, transaction did already complete */
457 return SUCCESS;
458 }
459 return transmit_request(this);
8d77edde
MW
460}
461
1396815a 462/**
3dd3c5f3 463 * Check for transactions in the queue and initiate the first transaction found.
1396815a 464 */
3dd3c5f3 465static status_t process_transaction_queue(private_ike_sa_t *this)
1396815a 466{
3dd3c5f3
MW
467 if (this->transaction_out)
468 {
469 /* already a transaction in progress */
470 return SUCCESS;
471 }
472
473 while (TRUE)
474 {
475 if (this->transaction_queue->remove_first(this->transaction_queue,
476 (void**)&this->transaction_out) != SUCCESS)
477 {
478 /* transaction queue empty */
479 return SUCCESS;
480 }
481 switch (transmit_request(this))
482 {
483 case SUCCESS:
484 return SUCCESS;
485 case DESTROY_ME:
486 /* critical, IKE_SA unusable, destroy immediately */
487 this->logger->log(this->logger, ERROR,
488 "transaction initiaton failed, deleting IKE_SA");
489 return DESTROY_ME;
490 default:
491 /* discard transaction, process next one */
492 this->logger->log(this->logger, ERROR,
493 "transaction initiation failed, discarded");
494 this->transaction_out->destroy(this->transaction_out);
495 this->transaction_out = NULL;
496 /* handle next transaction */
497 continue;
498 }
499 }
1396815a
MW
500}
501
8d77edde 502/**
3dd3c5f3 503 * Queue a new transaction and execute the next outstanding transaction
8d77edde 504 */
3dd3c5f3 505static status_t queue_transaction(private_ike_sa_t *this, transaction_t *transaction, bool prefer)
8d77edde 506{
3dd3c5f3
MW
507 /* inject next transaction */
508 if (transaction)
8d77edde 509 {
3dd3c5f3
MW
510 if (prefer)
511 {
512 this->transaction_queue->insert_first(this->transaction_queue, transaction);
513 }
514 else
515 {
516 this->transaction_queue->insert_last(this->transaction_queue, transaction);
517 }
8d77edde 518 }
3dd3c5f3
MW
519 /* process a transaction */
520 return process_transaction_queue(this);
8d77edde 521}
aebb38a0 522
aad398a7 523/**
3dd3c5f3 524 * process an incoming request.
aad398a7 525 */
3dd3c5f3 526static status_t process_request(private_ike_sa_t *this, message_t *request)
aad398a7 527{
3dd3c5f3
MW
528 transaction_t *last, *current = NULL;
529 message_t *response;
530 packet_t *packet;
531 u_int32_t request_mid;
532 status_t status;
b9d9f188 533
3dd3c5f3
MW
534 request_mid = request->get_message_id(request);
535 last = this->transaction_in;
536
537 /* check if message ID is correct */
538 if (last)
aad398a7 539 {
3dd3c5f3
MW
540 u_int32_t last_mid = last->get_message_id(last);
541
542 if (last_mid == request_mid)
543 {
544 /* retransmit detected */
545 this->logger->log(this->logger, ERROR,
546 "received retransmitted request for message ID %d, retransmitting response",
547 request_mid);
548 last->get_response(last, request, &response, &this->transaction_in_next);
549 packet = response->get_packet(response);
550 charon->send_queue->add(charon->send_queue, packet);
551 this->time_outbound = time(NULL);
552 return SUCCESS;
553 }
554
555 if (last_mid > request_mid)
556 {
557 /* something seriously wrong here, message id may not decrease */
558 this->logger->log(this->logger, ERROR,
559 "received request with message ID %d, excepted %d, ingored",
560 request_mid, last_mid + 1);
561 return FAILED;
562 }
563 /* we allow jumps in message IDs, as long as they are incremental */
564 if (last_mid + 1 < request_mid)
565 {
566 this->logger->log(this->logger, ERROR,
567 "received request with message ID %d, excepted %d",
568 request_mid, last_mid + 1);
569 }
aad398a7 570 }
3dd3c5f3 571 else
b9d9f188 572 {
3dd3c5f3
MW
573 if (request_mid != 0)
574 {
575 /* warn, but allow it */
576 this->logger->log(this->logger, CONTROL,
577 "first received request has message ID %d, excepted 0",
578 request_mid);
579 }
b9d9f188 580 }
ce461bbd 581
3dd3c5f3
MW
582 /* check if we already have a pre-created transaction for this request */
583 if (this->transaction_in_next)
ce461bbd 584 {
bcb95ced 585 current = this->transaction_in_next;
3dd3c5f3 586 this->transaction_in_next = NULL;
ce461bbd 587 }
bcb95ced 588 else
b9d9f188 589 {
3dd3c5f3
MW
590 current = transaction_create(&this->public, request);
591 if (current == NULL)
592 {
593 this->logger->log(this->logger, ERROR,
594 "no idea how to handle received message (%d), ignored",
595 request->get_exchange_type(request));
596 return FAILED;
597 }
ce461bbd
MW
598 }
599
3dd3c5f3
MW
600 /* send message. get_request() always gives a valid response */
601 status = current->get_response(current, request, &response, &this->transaction_in_next);
602 if (response->generate(response, this->crypter_out, this->signer_out, &packet) != SUCCESS)
ce461bbd 603 {
147fe509 604 this->logger->log(this->logger, ERROR,
3dd3c5f3
MW
605 "response generation failed, discarding transaction");
606 current->destroy(current);
b9d9f188
JH
607 return FAILED;
608 }
ce461bbd 609
3dd3c5f3
MW
610 charon->send_queue->add(charon->send_queue, packet);
611 this->time_outbound = time(NULL);
612 /* act depending on transaction result */
613 switch (status)
614 {
615 case DESTROY_ME:
616 /* transactions says we should destroy the IKE_SA, so do it */
617 current->destroy(current);
618 return DESTROY_ME;
619 default:
620 /* store for retransmission, destroy old transaction */
621 this->transaction_in = current;
622 if (last)
623 {
624 last->destroy(last);
625 }
626 return SUCCESS;
627 }
628}
b9d9f188 629
3dd3c5f3
MW
630/**
631 * process an incoming response
632 */
633static status_t process_response(private_ike_sa_t *this, message_t *response)
634{
635 transaction_t *current, *new = NULL;
ce461bbd 636
3dd3c5f3
MW
637 current = this->transaction_out;
638 /* check if message ID is that of our currently active transaction */
639 if (current == NULL ||
640 current->get_message_id(current) !=
641 response->get_message_id(response))
ce461bbd 642 {
3dd3c5f3
MW
643 this->logger->log(this->logger, ERROR,
644 "received response with message ID %d not requested, ignored");
ce461bbd
MW
645 return FAILED;
646 }
3dd3c5f3
MW
647
648 switch (current->conclude(current, response, &new))
b9d9f188 649 {
3dd3c5f3
MW
650 case DESTROY_ME:
651 /* state requested to destroy IKE_SA */
652 return DESTROY_ME;
653 default:
654 /* discard transaction, process next one */
655 break;
b9d9f188 656 }
3dd3c5f3
MW
657 /* transaction comleted, remove */
658 current->destroy(current);
659 this->transaction_out = NULL;
b9d9f188 660
3dd3c5f3
MW
661 /* queue new transaction */
662 return queue_transaction(this, new, TRUE);
663}
664
665/**
666 * send a notify back to the sender
667 */
668static void send_notify_response(private_ike_sa_t *this,
669 message_t *request,
670 notify_type_t type)
671{
672 notify_payload_t *notify;
673 message_t *response;
674 host_t *src, *dst;
675 packet_t *packet;
676
677 response = message_create();
678 dst = request->get_source(request);
679 src = request->get_destination(request);
680 response->set_source(response, src->clone(src));
681 response->set_destination(response, dst->clone(dst));
682 response->set_exchange_type(response, request->get_exchange_type(request));
683 response->set_request(response, FALSE);
684 response->set_message_id(response, request->get_message_id(request));
685 response->set_ike_sa_id(response, this->ike_sa_id);
686 notify = notify_payload_create_from_protocol_and_type(PROTO_NONE, type);
687 response->add_payload(response, (payload_t *)notify);
688 if (response->generate(response, this->crypter_out, this->signer_out, &packet) != SUCCESS)
b9d9f188 689 {
3dd3c5f3
MW
690 response->destroy(response);
691 return;
b9d9f188 692 }
3dd3c5f3
MW
693 charon->send_queue->add(charon->send_queue, packet);
694 this->time_outbound = time(NULL);
695 response->destroy(response);
696 return;
697}
698
699
700/**
701 * Implementation of ike_sa_t.process_message.
702 */
703static status_t process_message(private_ike_sa_t *this, message_t *message)
704{
705 status_t status;
706 bool is_request;
ce461bbd 707
3dd3c5f3 708 is_request = message->get_request(message);
ce461bbd 709
3dd3c5f3
MW
710 status = message->parse_body(message, this->crypter_in, this->signer_in);
711 if (status != SUCCESS)
b9d9f188 712 {
3dd3c5f3
MW
713 switch (status)
714 {
715 case NOT_SUPPORTED:
716 this->logger->log(this->logger, ERROR,
717 "ciritcal unknown payloads found");
718 if (is_request)
719 {
720 send_notify_response(this, message, UNSUPPORTED_CRITICAL_PAYLOAD);
721 }
722 break;
723 case PARSE_ERROR:
724 this->logger->log(this->logger, ERROR,
725 "message parsing failed");
726 if (is_request)
727 {
728 send_notify_response(this, message, INVALID_SYNTAX);
729 }
730 break;
731 case VERIFY_ERROR:
732 this->logger->log(this->logger, ERROR,
733 "message verification failed");
734 if (is_request)
735 {
736 send_notify_response(this, message, INVALID_SYNTAX);
737 }
738 break;
739 case FAILED:
740 this->logger->log(this->logger, ERROR,
741 "integrity check failed");
742 /* ignored */
743 break;
744 case INVALID_STATE:
745 this->logger->log(this->logger, ERROR,
746 "found encrypted message, but no keys available");
747 if (is_request)
748 {
749 send_notify_response(this, message, INVALID_SYNTAX);
750 }
751 default:
752 break;
753 }
754 this->logger->log(this->logger, ERROR,
755 "%s %s with message ID %d processing failed",
756 mapping_find(exchange_type_m, message->get_exchange_type(message)),
757 message->get_request(message) ? "request" : "response",
758 message->get_message_id(message));
b9d9f188 759 }
3dd3c5f3 760 else
ce461bbd 761 {
3dd3c5f3 762 /* check if message is trustworthy, and update connection information */
8dfbe71b 763 if (this->state == IKE_CREATED ||
3dd3c5f3
MW
764 message->get_exchange_type(message) != IKE_SA_INIT)
765 {
766 update_hosts(this, message->get_destination(message),
767 message->get_source(message));
768 this->time_inbound = time(NULL);
769 }
770 if (is_request)
771 {
772 status = process_request(this, message);
773 }
774 else
775 {
776 status = process_response(this, message);
777 }
ce461bbd 778 }
3dd3c5f3 779 return status;
aad398a7
JH
780}
781
782/**
3dd3c5f3 783 * Implementation of ike_sa_t.initiate.
aad398a7 784 */
8dfbe71b
MW
785static status_t initiate(private_ike_sa_t *this,
786 connection_t *connection, policy_t *policy)
aad398a7 787{
c0593835
MW
788 switch (this->state)
789 {
790 case IKE_CREATED:
791 {
792 /* in state CREATED, we must do the ike_sa_init
793 * and ike_auth transactions. Along with these,
794 * a CHILD_SA with the supplied policy is set up.
795 */
796 ike_sa_init_t *ike_sa_init;
797
45f76a7d
MW
798 this->logger->log(this->logger, CONTROL,
799 "initiating IKE_SA");
800
c0593835 801 set_name(this, connection->get_name(connection));
45f76a7d 802 DESTROY_IF(this->my_host);
c0593835
MW
803 this->my_host = connection->get_my_host(connection);
804 this->my_host = this->my_host->clone(this->my_host);
45f76a7d 805 DESTROY_IF(this->other_host);
c0593835
MW
806 this->other_host = connection->get_other_host(connection);
807 this->other_host = this->other_host->clone(this->other_host);
808
809 this->message_id_out = 1;
810 ike_sa_init = ike_sa_init_create(&this->public);
811 ike_sa_init->set_config(ike_sa_init, connection, policy);
812 return queue_transaction(this, (transaction_t*)ike_sa_init, TRUE);
813 }
814 case IKE_DELETING:
815 {
816 /* if we are in DELETING, we deny set up of a policy. */
45f76a7d
MW
817 this->logger->log(this->logger, CONTROL,
818 "creating CHILD_SA discarded, as IKE_SA is deleting");
c0593835
MW
819 policy->destroy(policy);
820 connection->destroy(connection);
821 return FAILED;
822 }
823 case IKE_CONNECTING:
824 case IKE_ESTABLISHED:
825 {
826 /* if we are ESTABLISHED or CONNECTING,we queue the
827 * transaction to create the CHILD_SA. It gets processed
828 * when the IKE_SA is ready to do so. We don't need the
829 * connection, as the IKE_SA is already established/establishing.
830 */
831 create_child_sa_t *create_child;
832
45f76a7d
MW
833 this->logger->log(this->logger, CONTROL,
834 "initiating CHILD_SA");
835
c0593835
MW
836 connection->destroy(connection);
837 create_child = create_child_sa_create(&this->public);
838 create_child->set_policy(create_child, policy);
839 return queue_transaction(this, (transaction_t*)create_child, FALSE);
840 }
841 }
842 return FAILED;
aad398a7
JH
843}
844
8dfbe71b
MW
845/**
846 * Implementation of ike_sa_t.acquire.
847 */
848static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
849{
45f76a7d
MW
850 connection_t *connection;
851 policy_t *policy;
852 iterator_t *iterator;
853 child_sa_t *current, *child_sa = NULL;
854 linked_list_t *my_ts, *other_ts;
855
856 if (this->state == IKE_DELETING)
857 {
858 this->logger->log(this->logger, CONTROL,
859 "acquiring CHILD_SA with reqid %d discarded, as IKE_SA is deleting",
860 reqid);
861 return FAILED;
862 }
863
864
865 /* find CHILD_SA */
866 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
867 while (iterator->iterate(iterator, (void**)&current))
868 {
869 if (current->get_reqid(current) == reqid)
870 {
871 iterator->remove(iterator);
872 child_sa = current;
873 break;
874 }
875 }
876 iterator->destroy(iterator);
877 if (!child_sa)
878 {
879 this->logger->log(this->logger, ERROR,
880 "CHILD_SA with reqid %d not found, unable to acquire",
881 reqid);
882 return FAILED;
883 }
884 my_ts = child_sa->get_my_traffic_selectors(child_sa);
885 other_ts = child_sa->get_other_traffic_selectors(child_sa);
886
887 policy = charon->policies->get_policy(charon->policies,
888 this->my_id, this->other_id,
889 my_ts, other_ts,
890 this->my_host, this->other_host);
891 child_sa->destroy(child_sa);
892 if (policy == NULL)
893 {
894 this->logger->log(this->logger, ERROR,
895 "no policy found to acquire CHILD_SA with reqid %d",
896 reqid);
897 return FAILED;
898 }
899
8dfbe71b
MW
900 switch (this->state)
901 {
902 case IKE_CREATED:
45f76a7d
MW
903 {
904 ike_sa_init_t *ike_sa_init;
905
906 this->logger->log(this->logger, CONTROL,
907 "acquiring CHILD_SA with reqid %d, IKE_SA setup needed",
908 reqid);
909
910 connection = charon->connections->get_connection_by_hosts(
911 charon->connections, this->my_host, this->other_host);
912
913 if (connection == NULL)
914 {
915 this->logger->log(this->logger, ERROR,
916 "no connection found to acquire IKE_SA for CHILD_SA with reqid %d",
917 reqid);
918 policy->destroy(policy);
919 return FAILED;
920 }
921
922 this->message_id_out = 1;
923 ike_sa_init = ike_sa_init_create(&this->public);
924 ike_sa_init->set_config(ike_sa_init, connection, policy);
925 return queue_transaction(this, (transaction_t*)ike_sa_init, TRUE);
926 }
927 case IKE_CONNECTING:
928 case IKE_ESTABLISHED:
929 {
930 create_child_sa_t *create_child;
931
932 this->logger->log(this->logger, CONTROL,
933 "acquiring CHILD_SA with reqid %d",
934 reqid);
935
936 create_child = create_child_sa_create(&this->public);
937 create_child->set_policy(create_child, policy);
938 return queue_transaction(this, (transaction_t*)create_child, FALSE);
939 }
940 default:
941 break;
942 }
943 return FAILED;
944}
945
946/**
947 * destroy a list of traffic selectors
948 */
949static void ts_list_destroy(linked_list_t *list)
950{
951 traffic_selector_t *ts;
952 while (list->remove_last(list, (void**)&ts) == SUCCESS)
953 {
954 ts->destroy(ts);
955 }
956 list->destroy(list);
957}
958
959/**
960 * compare two lists of traffic selectors for equality
961 */
962static bool ts_list_equals(linked_list_t *l1, linked_list_t *l2)
963{
964 bool equals = TRUE;
965 iterator_t *i1, *i2;
966 traffic_selector_t *t1, *t2;
967
968 i1 = l1->create_iterator(l1, TRUE);
969 i2 = l2->create_iterator(l2, TRUE);
970 while (i1->iterate(i1, (void**)&t1) && i2->iterate(i2, (void**)&t2))
971 {
972 if (!t1->equals(t1, t2))
973 {
974 equals = FALSE;
8dfbe71b 975 break;
45f76a7d
MW
976 }
977 }
978 /* check if one iterator is not at the end */
979 if (i1->has_next(i1) || i2->has_next(i2))
980 {
981 equals = FALSE;
982 }
983 i1->destroy(i1);
984 i2->destroy(i2);
985 return equals;
986}
987
988/**
989 * Implementation of ike_sa_t.route.
990 */
991static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t *policy)
992{
993 child_sa_t *child_sa = NULL;
994 iterator_t *iterator;
995 linked_list_t *my_ts, *other_ts;
996 status_t status;
997
998 /* check if not already routed*/
999 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
1000 while (iterator->iterate(iterator, (void**)&child_sa))
1001 {
1002 linked_list_t *my_ts_conf, *other_ts_conf;
1003
1004 my_ts = child_sa->get_my_traffic_selectors(child_sa);
1005 other_ts = child_sa->get_other_traffic_selectors(child_sa);
1006
1007 my_ts_conf = policy->get_my_traffic_selectors(policy, this->my_host);
1008 other_ts_conf = policy->get_other_traffic_selectors(policy, this->other_host);
1009
1010 if (ts_list_equals(my_ts, my_ts_conf) &&
1011 ts_list_equals(other_ts, other_ts_conf))
1012 {
1013 ts_list_destroy(my_ts_conf);
1014 ts_list_destroy(other_ts_conf);
1015 iterator->destroy(iterator);
1016 this->logger->log(this->logger, CONTROL,
1017 "a CHILD_SA with such a policy already routed");
1018
1019 return FAILED;
1020 }
1021 ts_list_destroy(my_ts_conf);
1022 ts_list_destroy(other_ts_conf);
1023 }
1024 iterator->destroy(iterator);
1025
1026 switch (this->state)
1027 {
1028 case IKE_CREATED:
8dfbe71b 1029 case IKE_CONNECTING:
45f76a7d
MW
1030 /* we update IKE_SA information as good as possible,
1031 * this allows us to set up the SA later when an acquire comes in. */
1032 if (this->my_id->get_type(this->my_id) == ID_ANY)
1033 {
1034 this->my_id->destroy(this->my_id);
1035 this->my_id = policy->get_my_id(policy);
1036 this->my_id = this->my_id->clone(this->my_id);
1037 }
1038 if (this->other_id->get_type(this->other_id) == ID_ANY)
1039 {
1040 this->other_id->destroy(this->other_id);
1041 this->other_id = policy->get_other_id(policy);
1042 this->other_id = this->other_id->clone(this->other_id);
1043 }
1044 if (this->my_host->is_anyaddr(this->my_host))
1045 {
1046 this->my_host->destroy(this->my_host);
1047 this->my_host = connection->get_my_host(connection);
1048 this->my_host = this->my_host->clone(this->my_host);
1049 }
1050 if (this->other_host->is_anyaddr(this->other_host))
1051 {
1052 this->other_host->destroy(this->other_host);
1053 this->other_host = connection->get_other_host(connection);
1054 this->other_host = this->other_host->clone(this->other_host);
1055 }
1056 set_name(this, connection->get_name(connection));
1057 break;
8dfbe71b 1058 case IKE_ESTABLISHED:
45f76a7d 1059 /* nothing to do */
8dfbe71b
MW
1060 break;
1061 case IKE_DELETING:
1062 /* deny */
45f76a7d 1063 return FAILED;
8dfbe71b 1064 }
45f76a7d
MW
1065
1066 child_sa = child_sa_create(0, this->my_host, this->other_host, 0, 0, FALSE);
1067 my_ts = policy->get_my_traffic_selectors(policy, this->my_host);
1068 other_ts = policy->get_other_traffic_selectors(policy, this->other_host);
1069 status = child_sa->add_policies(child_sa, my_ts, other_ts);
1070 ts_list_destroy(my_ts);
1071 ts_list_destroy(other_ts);
1072 this->child_sas->insert_last(this->child_sas, child_sa);
1073
1074 return status;
8dfbe71b
MW
1075}
1076
1077/**
45f76a7d 1078 * Implementation of ike_sa_t.unroute.
8dfbe71b 1079 */
45f76a7d 1080static status_t unroute(private_ike_sa_t *this, policy_t *policy)
8dfbe71b 1081{
45f76a7d
MW
1082 iterator_t *iterator;
1083 child_sa_t *child_sa = NULL;
1084 linked_list_t *my_ts, *other_ts, *my_ts_conf, *other_ts_conf;
1085
1086 /* find CHILD_SA in ROUTED state */
1087 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
1088 while (iterator->iterate(iterator, (void**)&child_sa))
1089 {
1090 if (child_sa->get_state(child_sa) == CHILD_ROUTED)
1091 {
1092 my_ts = child_sa->get_my_traffic_selectors(child_sa);
1093 other_ts = child_sa->get_other_traffic_selectors(child_sa);
1094
1095 my_ts_conf = policy->get_my_traffic_selectors(policy, this->my_host);
1096 other_ts_conf = policy->get_other_traffic_selectors(policy, this->other_host);
1097
1098 if (ts_list_equals(my_ts, my_ts_conf) &&
1099 ts_list_equals(other_ts, other_ts_conf))
1100 {
1101 iterator->remove(iterator);
1102 child_sa->destroy(child_sa);
1103 ts_list_destroy(my_ts_conf);
1104 ts_list_destroy(other_ts_conf);
1105 break;
1106 }
1107 ts_list_destroy(my_ts_conf);
1108 ts_list_destroy(other_ts_conf);
1109 }
1110 }
1111 iterator->destroy(iterator);
1112 /* if we are not established, and we have no more routed childs, remove whole SA */
1113 if (this->state == IKE_CREATED &&
1114 this->child_sas->get_count(this->child_sas) == 0)
1115 {
1116 return DESTROY_ME;
1117 }
1118 return SUCCESS;
8dfbe71b
MW
1119}
1120
f890d8fe 1121/**
3dd3c5f3 1122 * Implementation of ike_sa_t.send_dpd
f890d8fe 1123 */
3dd3c5f3 1124static status_t send_dpd(private_ike_sa_t *this)
f890d8fe 1125{
3dd3c5f3
MW
1126 send_dpd_job_t *job;
1127 time_t diff, interval;
1128 status_t status = SUCCESS;
1129
1130 interval = charon->configuration->get_dpd_interval(charon->configuration);
1131
1132 if (this->transaction_out)
1133 {
1134 /* there is a transaction in progress. Come back later */
1135 diff = 0;
1136 }
1137 else
1138 {
1139 /* check if there was any inbound traffic */
1140 time_t last_in, now;
1141 last_in = get_time_inbound(this);
1142 now = time(NULL);
1143 diff = now - last_in;
1144 if (diff >= interval)
1145 {
1146 /* to long ago, initiate dead peer detection */
1147 dead_peer_detection_t *dpd;
1148 this->logger->log(this->logger, CONTROL, "sending DPD request");
bcb95ced 1149 dpd = dead_peer_detection_create(&this->public);
3dd3c5f3
MW
1150 status = queue_transaction(this, (transaction_t*)dpd, FALSE);
1151 diff = 0;
1152 }
1153 }
1154 /* recheck in "interval" seconds */
1155 job = send_dpd_job_create(this->ike_sa_id);
1156 charon->event_queue->add_relative(charon->event_queue, (job_t*)job,
1157 (interval - diff) * 1000);
1158 return SUCCESS;
f890d8fe
JH
1159}
1160
1161/**
3dd3c5f3 1162 * Implementation of ike_sa_t.send_keepalive
f890d8fe 1163 */
3dd3c5f3 1164static void send_keepalive(private_ike_sa_t *this)
f890d8fe 1165{
3dd3c5f3
MW
1166 send_keepalive_job_t *job;
1167 time_t last_out, now, diff, interval;
1168
1169 last_out = get_time_outbound(this);
1170 now = time(NULL);
1171
1172 diff = now - last_out;
1173 interval = charon->configuration->get_keepalive_interval(charon->configuration);
1174
1175 if (diff >= interval)
1176 {
3dd3c5f3
MW
1177 packet_t *packet;
1178 chunk_t data;
1179
1180 packet = packet_create();
8dfbe71b
MW
1181 packet->set_source(packet, this->my_host->clone(this->my_host));
1182 packet->set_destination(packet, this->other_host->clone(this->other_host));
3dd3c5f3
MW
1183 data.ptr = malloc(1);
1184 data.ptr[0] = 0xFF;
1185 data.len = 1;
1186 packet->set_data(packet, data);
1187 charon->send_queue->add(charon->send_queue, packet);
1188 this->logger->log(this->logger, CONTROL, "sending keep alive");
1189 diff = 0;
1190 }
1191 job = send_keepalive_job_create(this->ike_sa_id);
1192 charon->event_queue->add_relative(charon->event_queue, (job_t*)job,
1193 (interval - diff) * 1000);
f890d8fe
JH
1194}
1195
ccf783d2 1196/**
3dd3c5f3 1197 * Implementation of ike_sa_t.get_state.
ccf783d2 1198 */
3dd3c5f3 1199static ike_sa_state_t get_state(private_ike_sa_t *this)
ccf783d2 1200{
3dd3c5f3 1201 return this->state;
ccf783d2
MW
1202}
1203
1204/**
3dd3c5f3 1205 * Implementation of ike_sa_t.set_state.
ccf783d2 1206 */
3dd3c5f3 1207static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
ccf783d2 1208{
3dd3c5f3
MW
1209 this->logger->log(this->logger, CONTROL, "state change: %s => %s",
1210 mapping_find(ike_sa_state_m, this->state),
1211 mapping_find(ike_sa_state_m, state));
bcb95ced 1212 if (state == IKE_ESTABLISHED)
3dd3c5f3 1213 {
3dd3c5f3 1214 this->logger->log(this->logger, AUDIT, "IKE_SA established: %s[%s]...%s[%s]",
8dfbe71b
MW
1215 this->my_host->get_string(this->my_host),
1216 this->my_id->get_string(this->my_id),
1217 this->other_host->get_string(this->other_host),
1218 this->other_id->get_string(this->other_id));
3dd3c5f3
MW
1219
1220 send_dpd(this);
1221 }
1222 this->state = state;
ccf783d2
MW
1223}
1224
2f89902d 1225/**
8dfbe71b 1226 * Implementation of protected_ike_sa_t.get_prf.
2f89902d 1227 */
8dfbe71b 1228static prf_t *get_prf(private_ike_sa_t *this)
2f89902d 1229{
8dfbe71b 1230 return this->prf;
2f89902d
MW
1231}
1232
aad398a7 1233/**
8dfbe71b 1234 * Implementation of protected_ike_sa_t.get_prf.
aad398a7 1235 */
8dfbe71b 1236static prf_t *get_child_prf(private_ike_sa_t *this)
aad398a7 1237{
8dfbe71b 1238 return this->child_prf;
aad398a7
JH
1239}
1240
aad398a7 1241/**
8dfbe71b 1242 * Implementation of protected_ike_sa_t.get_prf_auth_i.
aad398a7 1243 */
8dfbe71b 1244static prf_t *get_prf_auth_i(private_ike_sa_t *this)
aad398a7 1245{
8dfbe71b 1246 return this->prf_auth_i;
aad398a7
JH
1247}
1248
283dbcc5 1249/**
8dfbe71b 1250 * Implementation of protected_ike_sa_t.get_prf_auth_r.
283dbcc5 1251 */
8dfbe71b 1252static prf_t *get_prf_auth_r(private_ike_sa_t *this)
283dbcc5 1253{
8dfbe71b 1254 return this->prf_auth_r;
283dbcc5
MW
1255}
1256
ae3012a0 1257/**
8dfbe71b 1258 * Implementation of ike_sa_t.get_id.
0df63d6b 1259 */
8dfbe71b 1260static ike_sa_id_t* get_id(private_ike_sa_t *this)
0df63d6b 1261{
8dfbe71b 1262 return this->ike_sa_id;
0df63d6b
JH
1263}
1264
0fdc3c7f 1265/**
8dfbe71b 1266 * Implementation of ike_sa_t.get_my_id.
0fdc3c7f 1267 */
8dfbe71b 1268static identification_t* get_my_id(private_ike_sa_t *this)
0fdc3c7f 1269{
8dfbe71b 1270 return this->my_id;
8d68033e
JH
1271}
1272
1273/**
8dfbe71b 1274 * Implementation of ike_sa_t.set_my_id.
8d68033e 1275 */
8dfbe71b 1276static void set_my_id(private_ike_sa_t *this, identification_t *me)
8d68033e 1277{
c0593835 1278 DESTROY_IF(this->my_id);
8dfbe71b 1279 this->my_id = me;
0fdc3c7f
JH
1280}
1281
30b5b412 1282/**
8dfbe71b 1283 * Implementation of ike_sa_t.get_other_id.
30b5b412 1284 */
8dfbe71b 1285static identification_t* get_other_id(private_ike_sa_t *this)
30b5b412 1286{
8dfbe71b 1287 return this->other_id;
3dd3c5f3 1288}
8dfbe71b 1289
3dd3c5f3 1290/**
8dfbe71b 1291 * Implementation of ike_sa_t.set_other_id.
3dd3c5f3 1292 */
8dfbe71b 1293static void set_other_id(private_ike_sa_t *this, identification_t *other)
3dd3c5f3 1294{
c0593835 1295 DESTROY_IF(this->other_id);
8dfbe71b 1296 this->other_id = other;
30b5b412
MW
1297}
1298
8d77edde 1299/**
3dd3c5f3 1300 * Implementation of protected_ike_sa_t.build_transforms.
8d77edde 1301 */
3dd3c5f3
MW
1302static status_t build_transforms(private_ike_sa_t *this, proposal_t *proposal,
1303 diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r,
1304 bool initiator)
8d77edde 1305{
3dd3c5f3
MW
1306 chunk_t nonces, nonces_spis, skeyseed, key, secret;
1307 u_int64_t spi_i, spi_r;
1308 prf_plus_t *prf_plus;
1309 algorithm_t *algo;
1310 size_t key_size;
1311 crypter_t *crypter_i, *crypter_r;
1312 signer_t *signer_i, *signer_r;
8d77edde 1313
3dd3c5f3
MW
1314 /* Build the PRF+ instance for deriving keys */
1315 if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo))
8d77edde 1316 {
3dd3c5f3
MW
1317 this->logger->log(this->logger, ERROR, "no PSEUDO_RANDOM_FUNCTION selected!");
1318 return FAILED;
8d77edde 1319 }
3dd3c5f3
MW
1320 this->prf = prf_create(algo->algorithm);
1321 if (this->prf == NULL)
8d77edde 1322 {
3dd3c5f3
MW
1323 this->logger->log(this->logger, ERROR, "PSEUDO_RANDOM_FUNCTION %s not supported!",
1324 mapping_find(pseudo_random_function_m, algo->algorithm));
1325 return FAILED;
8d77edde
MW
1326 }
1327
3dd3c5f3
MW
1328 /* nonces = nonce_i | nonce_r */
1329 nonces = chunk_alloc(nonce_i.len + nonce_r.len);
1330 memcpy(nonces.ptr, nonce_i.ptr, nonce_i.len);
1331 memcpy(nonces.ptr + nonce_i.len, nonce_r.ptr, nonce_r.len);
8d77edde 1332
3dd3c5f3
MW
1333 /* prf_seed = nonce_i | nonce_r | spi_i | spi_r */
1334 nonces_spis = chunk_alloc(nonces.len + 16);
1335 memcpy(nonces_spis.ptr, nonces.ptr, nonces.len);
1336 spi_i = this->ike_sa_id->get_initiator_spi(this->ike_sa_id);
1337 spi_r = this->ike_sa_id->get_responder_spi(this->ike_sa_id);
1338 memcpy(nonces_spis.ptr + nonces.len, &spi_i, 8);
1339 memcpy(nonces_spis.ptr + nonces.len + 8, &spi_r, 8);
1340
1341 /* SKEYSEED = prf(Ni | Nr, g^ir) */
1342 dh->get_shared_secret(dh, &secret);
1343 this->logger->log_chunk(this->logger, PRIVATE, "shared Diffie Hellman secret", secret);
1344 this->prf->set_key(this->prf, nonces);
1345 this->prf->allocate_bytes(this->prf, secret, &skeyseed);
1346 this->logger->log_chunk(this->logger, PRIVATE|LEVEL1, "SKEYSEED", skeyseed);
1347 chunk_free(&secret);
8d77edde 1348
3dd3c5f3
MW
1349 /* prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr )
1350 * = SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr
1351 */
1352 this->prf->set_key(this->prf, skeyseed);
1353 prf_plus = prf_plus_create(this->prf, nonces_spis);
8d77edde 1354
3dd3c5f3
MW
1355 /* clean up unused stuff */
1356 chunk_free(&nonces);
1357 chunk_free(&nonces_spis);
1358 chunk_free(&skeyseed);
1359
1360 /* SK_d used for prf+ to derive keys for child SAs */
1361 this->child_prf = prf_create(algo->algorithm);
1362 key_size = this->child_prf->get_key_size(this->child_prf);
1363 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1364 this->logger->log_chunk(this->logger, PRIVATE, "Sk_d secret", key);
1365 this->child_prf->set_key(this->child_prf, key);
1366 chunk_free(&key);
1367
1368 /* SK_ai/SK_ar used for integrity protection */
1369 if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &algo))
8d77edde 1370 {
3dd3c5f3 1371 this->logger->log(this->logger, ERROR, "no INTEGRITY_ALGORITHM selected?!");
8d77edde
MW
1372 return FAILED;
1373 }
1374
3dd3c5f3
MW
1375 signer_i = signer_create(algo->algorithm);
1376 signer_r = signer_create(algo->algorithm);
1377 if (signer_i == NULL || signer_r == NULL)
1396815a 1378 {
3dd3c5f3
MW
1379 this->logger->log(this->logger, ERROR, "INTEGRITY_ALGORITHM %s not supported!",
1380 mapping_find(integrity_algorithm_m,algo->algorithm));
1381 return FAILED;
1396815a 1382 }
3dd3c5f3
MW
1383 key_size = signer_i->get_key_size(signer_i);
1384
1385 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1386 this->logger->log_chunk(this->logger, CONTROL|LEVEL1, "Sk_ai secret", key);
1387 signer_i->set_key(signer_i, key);
1388 chunk_free(&key);
1396815a 1389
3dd3c5f3
MW
1390 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1391 this->logger->log_chunk(this->logger, CONTROL|LEVEL1, "Sk_ar secret", key);
1392 signer_r->set_key(signer_r, key);
1393 chunk_free(&key);
1396815a 1394
3dd3c5f3 1395 if (initiator)
1396815a 1396 {
0d379627
MW
1397 this->signer_in = signer_r;
1398 this->signer_out = signer_i;
1396815a
MW
1399 }
1400 else
1401 {
0d379627
MW
1402 this->signer_in = signer_i;
1403 this->signer_out = signer_r;
1396815a 1404 }
3dd3c5f3
MW
1405
1406 /* SK_ei/SK_er used for encryption */
1407 if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &algo))
1396815a 1408 {
3dd3c5f3
MW
1409 this->logger->log(this->logger, ERROR, "no ENCRYPTION_ALGORITHM selected!");
1410 return FAILED;
1411 }
1412 crypter_i = crypter_create(algo->algorithm, algo->key_size / 8);
1413 crypter_r = crypter_create(algo->algorithm, algo->key_size / 8);
1414 if (crypter_i == NULL || crypter_r == NULL)
1415 {
1416 this->logger->log(this->logger, ERROR,
1417 "ENCRYPTION_ALGORITHM %s (key size %d) not supported!",
1418 mapping_find(encryption_algorithm_m, algo->algorithm),
1419 algo->key_size);
1420 return FAILED;
1396815a 1421 }
3dd3c5f3 1422 key_size = crypter_i->get_key_size(crypter_i);
1396815a 1423
3dd3c5f3
MW
1424 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1425 this->logger->log_chunk(this->logger, PRIVATE, "Sk_ei secret", key);
1426 crypter_i->set_key(crypter_i, key);
1427 chunk_free(&key);
1428
1429 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1430 this->logger->log_chunk(this->logger, PRIVATE, "Sk_er secret", key);
1431 crypter_r->set_key(crypter_r, key);
1432 chunk_free(&key);
1433
1434 if (initiator)
1396815a 1435 {
0d379627
MW
1436 this->crypter_in = crypter_r;
1437 this->crypter_out = crypter_i;
1396815a 1438 }
3dd3c5f3
MW
1439 else
1440 {
0d379627
MW
1441 this->crypter_in = crypter_i;
1442 this->crypter_out = crypter_r;
3dd3c5f3
MW
1443 }
1444
1445 /* SK_pi/SK_pr used for authentication */
1446 proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo);
1447 this->prf_auth_i = prf_create(algo->algorithm);
1448 this->prf_auth_r = prf_create(algo->algorithm);
1449
1450 key_size = this->prf_auth_i->get_key_size(this->prf_auth_i);
1451 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1452 this->logger->log_chunk(this->logger, PRIVATE, "Sk_pi secret", key);
1453 this->prf_auth_i->set_key(this->prf_auth_i, key);
1454 chunk_free(&key);
1455
1456 prf_plus->allocate_bytes(prf_plus, key_size, &key);
1457 this->logger->log_chunk(this->logger, PRIVATE, "Sk_pr secret", key);
1458 this->prf_auth_r->set_key(this->prf_auth_r, key);
1459 chunk_free(&key);
1460
1461 /* all done, prf_plus not needed anymore */
1462 prf_plus->destroy(prf_plus);
1463
1464 return SUCCESS;
1396815a
MW
1465}
1466
32b6500f 1467/**
3dd3c5f3 1468 * Implementation of protected_ike_sa_t.add_child_sa.
32b6500f 1469 */
3dd3c5f3 1470static void add_child_sa(private_ike_sa_t *this, child_sa_t *child_sa)
32b6500f 1471{
3dd3c5f3 1472 this->child_sas->insert_last(this->child_sas, child_sa);
32b6500f
MW
1473}
1474
45f76a7d
MW
1475/**
1476 * Implementation of protected_ike_sa_t.has_child_sa.
1477 */
1478static bool has_child_sa(private_ike_sa_t *this, u_int32_t reqid)
1479{
1480 iterator_t *iterator;
1481 child_sa_t *current;
1482 bool found = FALSE;
1483
1484 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
1485 while (iterator->iterate(iterator, (void**)&current))
1486 {
1487 if (current->get_reqid(current) == reqid)
1488 {
1489 found = TRUE;
1490 break;
1491 }
1492 }
1493 iterator->destroy(iterator);
1494 return found;
1495}
1496
695723d4
MW
1497/**
1498 * Implementation of protected_ike_sa_t.get_child_sa.
1499 */
698d7749
MW
1500static child_sa_t* get_child_sa(private_ike_sa_t *this, protocol_id_t protocol,
1501 u_int32_t spi, bool inbound)
695723d4
MW
1502{
1503 iterator_t *iterator;
1504 child_sa_t *current, *found = NULL;
1505
45f76a7d 1506 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
695723d4
MW
1507 while (iterator->has_next(iterator))
1508 {
1509 iterator->current(iterator, (void**)&current);
698d7749 1510 if (current->get_spi(current, inbound) == spi &&
45f76a7d 1511 current->get_protocol(current) == protocol)
695723d4
MW
1512 {
1513 found = current;
1514 }
1515 }
1516 iterator->destroy(iterator);
1517 return found;
8d77edde
MW
1518}
1519
1520/**
1521 * Implementation of ike_sa_t.rekey_child_sa.
1522 */
698d7749 1523static status_t rekey_child_sa(private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi)
8d77edde 1524{
698d7749 1525 create_child_sa_t *rekey;
8d77edde 1526 child_sa_t *child_sa;
8d77edde 1527
698d7749
MW
1528 child_sa = get_child_sa(this, protocol, spi, TRUE);
1529 if (child_sa == NULL)
8d77edde 1530 {
698d7749 1531 return NOT_FOUND;
8d77edde
MW
1532 }
1533
bcb95ced 1534 rekey = create_child_sa_create(&this->public);
698d7749
MW
1535 rekey->rekeys_child(rekey, child_sa);
1536 return queue_transaction(this, (transaction_t*)rekey, FALSE);
1537}
1538
1539/**
1540 * Implementation of ike_sa_t.delete_child_sa.
1541 */
1542static status_t delete_child_sa(private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi)
1543{
1544 delete_child_sa_t *del;
1545 child_sa_t *child_sa;
1546
1547 child_sa = get_child_sa(this, protocol, spi, TRUE);
8d77edde
MW
1548 if (child_sa == NULL)
1549 {
698d7749 1550 return NOT_FOUND;
8d77edde
MW
1551 }
1552
bcb95ced 1553 del = delete_child_sa_create(&this->public);
698d7749
MW
1554 del->set_child_sa(del, child_sa);
1555 return queue_transaction(this, (transaction_t*)del, FALSE);
1556}
1557
1558/**
1559 * Implementation of protected_ike_sa_t.destroy_child_sa.
1560 */
1561static status_t destroy_child_sa(private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi)
1562{
1563 iterator_t *iterator;
1564 child_sa_t *child_sa;
1565 status_t status = NOT_FOUND;
8d77edde 1566
698d7749
MW
1567 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
1568 while (iterator->iterate(iterator, (void**)&child_sa))
1569 {
1570 if (child_sa->get_protocol(child_sa) == protocol &&
1571 child_sa->get_spi(child_sa, TRUE) == spi)
1572 {
1573 child_sa->destroy(child_sa);
1574 iterator->remove(iterator);
1575 status = SUCCESS;
1576 break;
1577 }
8d77edde 1578 }
698d7749
MW
1579 iterator->destroy(iterator);
1580 return status;
8d77edde
MW
1581}
1582
aad398a7 1583
b92eef28
MW
1584/**
1585 * Implementation of protected_ike_sa_t.log_status.
1586 */
e168ee17 1587static void log_status(private_ike_sa_t *this, logger_t *logger, char *name)
b92eef28
MW
1588{
1589 iterator_t *iterator;
1590 child_sa_t *child_sa;
8dfbe71b 1591 char *my_host, *other_host, *my_id, *other_id;
b92eef28 1592
8dfbe71b 1593 if (name == NULL || streq(name, this->name))
e168ee17 1594 {
8dfbe71b 1595 if (logger == NULL)
e168ee17 1596 {
8dfbe71b 1597 logger = this->logger;
e168ee17 1598 }
8dfbe71b
MW
1599
1600 my_host = this->my_host ?
1601 this->my_host->get_string(this->my_host) : "(unknown)";
1602 other_host = this->other_host ?
1603 this->other_host->get_string(this->other_host) : "(unknown)";
1604 my_id = this->my_id ?
1605 this->my_id->get_string(this->my_id) : "(unknown)";
1606 other_id = this->other_id ?
1607 this->other_id->get_string(this->other_id) : "(unknown)";
1608
1609 logger->log(logger, CONTROL|LEVEL1,
1610 " \"%s\": IKE_SA in state %s, SPIs: 0x%.16llx 0x%.16llx",
1611 this->name,
1612 mapping_find(ike_sa_state_m, this->state),
1613 this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
1614 this->ike_sa_id->get_responder_spi(this->ike_sa_id));
1615 logger->log(logger, CONTROL, " \"%s\": %s[%s]...%s[%s]",
1616 this->name, my_host, my_id, other_host, other_id);
1617
1618 iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
1619 while (iterator->has_next(iterator))
1620 {
1621 iterator->current(iterator, (void**)&child_sa);
1622 child_sa->log_status(child_sa, logger, this->name);
1623 }
1624 iterator->destroy(iterator);
e168ee17 1625 }
b92eef28
MW
1626}
1627
4a5bba25
MW
1628/**
1629 * Implementation of public_ike_sa_t.delete.
1630 */
1631static status_t delete_(private_ike_sa_t *this)
1632{
45f76a7d 1633 switch (this->state)
325e4977 1634 {
45f76a7d
MW
1635 case IKE_CONNECTING:
1636 case IKE_ESTABLISHED:
1637 {
1638 delete_ike_sa_t *delete_ike_sa;
1639 delete_ike_sa = delete_ike_sa_create(&this->public);
1640 if (this->transaction_out)
1641 {
1642 /* already a transaction in progress. As this may hang
1643 * around a while, we don't inform the other peer. */
1644 return DESTROY_ME;
1645 }
1646 return queue_transaction(this, (transaction_t*)delete_ike_sa, FALSE);
1647 }
1648 case IKE_CREATED:
1649 case IKE_DELETING:
1650 default:
1651 {
1652 return DESTROY_ME;
1653 }
325e4977 1654 }
1396815a
MW
1655}
1656
bcb95ced
MW
1657/**
1658 * Implementation of ike_sa_t.get_next_message_id.
1659 */
1660static u_int32_t get_next_message_id (private_ike_sa_t *this)
1661{
1662 return this->message_id_out++;
1663}
1664
1396815a 1665/**
3dd3c5f3 1666 * Implementation of ike_sa_t.is_natt_enabled.
1396815a 1667 */
3dd3c5f3 1668static bool is_natt_enabled (private_ike_sa_t *this)
1396815a
MW
1669{
1670 return this->nat_here || this->nat_there;
1671}
1672
1673/**
3dd3c5f3 1674 * Implementation of protected_ike_sa_t.enable_natt.
1396815a 1675 */
3dd3c5f3 1676static void enable_natt (private_ike_sa_t *this, bool local)
1396815a 1677{
3dd3c5f3 1678 if (local)
2f89902d 1679 {
3dd3c5f3
MW
1680 this->logger->log(this->logger, CONTROL,
1681 "local host is behind NAT, using NAT-T, scheduled keep alives");
1682 this->nat_here = TRUE;
1683 send_keepalive(this);
1684 }
1685 else
1686 {
1687 this->logger->log(this->logger, CONTROL,
1688 "remote host is behind NAT, using NAT-T");
1689 this->nat_there = TRUE;
2f89902d 1690 }
1396815a
MW
1691}
1692
60a6167a 1693/**
ae3012a0 1694 * Implementation of protected_ike_sa_t.destroy.
60a6167a 1695 */
4a5bba25 1696static void destroy(private_ike_sa_t *this)
60a6167a 1697{
30b5b412 1698 child_sa_t *child_sa;
3dd3c5f3 1699 transaction_t *transaction;
8dfbe71b 1700 char *my_host, *other_host, *my_id, *other_id;
30b5b412 1701
971218c3 1702 this->logger->log(this->logger, CONTROL|LEVEL2, "going to destroy IKE SA %llu:%llu, role %s",
94b0f906
JH
1703 this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
1704 this->ike_sa_id->get_responder_spi(this->ike_sa_id),
1705 this->ike_sa_id->is_initiator(this->ike_sa_id) ? "initiator" : "responder");
4a5bba25 1706
bcb95ced 1707 if (this->state == IKE_ESTABLISHED)
4a5bba25 1708 {
3dd3c5f3
MW
1709 this->logger->log(this->logger, ERROR,
1710 "destroying an established IKE SA without knowledge from remote peer!");
4a5bba25 1711 }
8323a9c1 1712
30b5b412 1713 while (this->child_sas->remove_last(this->child_sas, (void**)&child_sa) == SUCCESS)
60a6167a 1714 {
30b5b412 1715 child_sa->destroy(child_sa);
60a6167a 1716 }
7ba38761 1717 this->child_sas->destroy(this->child_sas);
87a217f9 1718
3dd3c5f3
MW
1719 while (this->transaction_queue->remove_last(this->transaction_queue, (void**)&transaction) == SUCCESS)
1720 {
1721 transaction->destroy(transaction);
1722 }
1723 this->transaction_queue->destroy(this->transaction_queue);
8dfbe71b
MW
1724
1725 DESTROY_IF(this->transaction_in);
1726 DESTROY_IF(this->transaction_in_next);
1727 DESTROY_IF(this->transaction_out);
1728 DESTROY_IF(this->crypter_in);
1729 DESTROY_IF(this->crypter_out);
1730 DESTROY_IF(this->signer_in);
1731 DESTROY_IF(this->signer_out);
1732 DESTROY_IF(this->prf);
1733 DESTROY_IF(this->child_prf);
1734 DESTROY_IF(this->prf_auth_i);
1735 DESTROY_IF(this->prf_auth_r);
1736
1737 my_host = this->my_host ?
1738 this->my_host->get_string(this->my_host) : "(unknown)";
1739 other_host = this->other_host ?
1740 this->other_host->get_string(this->other_host) : "(unknown)";
1741 my_id = this->my_id ?
1742 this->my_id->get_string(this->my_id) : "(unknown)";
1743 other_id = this->other_id ?
1744 this->other_id->get_string(this->other_id) : "(unknown)";
1745
1746 this->logger->log(this->logger, AUDIT,
1747 "IKE_SA deleted between %s[%s]...%s[%s]",
1748 my_host, my_id, other_host, other_id);
1749
1750 DESTROY_IF(this->my_host);
1751 DESTROY_IF(this->other_host);
1752 DESTROY_IF(this->my_id);
1753 DESTROY_IF(this->other_id);
1754
1755 free(this->name);
87a217f9 1756 this->ike_sa_id->destroy(this->ike_sa_id);
5113680f 1757 free(this);
7ba38761
JH
1758}
1759
1760/*
39b2903f 1761 * Described in header.
7ba38761
JH
1762 */
1763ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
1764{
5113680f 1765 private_ike_sa_t *this = malloc_thing(private_ike_sa_t);
8d77edde 1766
7ba38761 1767 /* Public functions */
3dd3c5f3
MW
1768 this->public.get_state = (ike_sa_state_t(*)(ike_sa_t*)) get_state;
1769 this->public.set_state = (void(*)(ike_sa_t*,ike_sa_state_t)) set_state;
8dfbe71b
MW
1770 this->public.get_name = (char*(*)(ike_sa_t*))get_name;
1771 this->public.set_name = (void(*)(ike_sa_t*,char*))set_name;
3dd3c5f3 1772 this->public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message;
8dfbe71b 1773 this->public.initiate = (status_t(*)(ike_sa_t*,connection_t*,policy_t*)) initiate;
45f76a7d
MW
1774 this->public.route = (status_t(*)(ike_sa_t*,connection_t*,policy_t*)) route;
1775 this->public.unroute = (status_t(*)(ike_sa_t*,policy_t*)) unroute;
8dfbe71b 1776 this->public.acquire = (status_t(*)(ike_sa_t*,u_int32_t)) acquire;
3dd3c5f3 1777 this->public.get_id = (ike_sa_id_t*(*)(ike_sa_t*)) get_id;
8dfbe71b
MW
1778 this->public.get_my_host = (host_t*(*)(ike_sa_t*)) get_my_host;
1779 this->public.get_other_host = (host_t*(*)(ike_sa_t*)) get_other_host;
1780 this->public.get_my_id = (identification_t*(*)(ike_sa_t*)) get_my_id;
1781 this->public.set_my_id = (void(*)(ike_sa_t*,identification_t*)) set_my_id;
1782 this->public.get_other_id = (identification_t*(*)(ike_sa_t*)) get_other_id;
1783 this->public.set_other_id = (void(*)(ike_sa_t*,identification_t*)) set_other_id;
bcb95ced 1784 this->public.get_next_message_id = (u_int32_t(*)(ike_sa_t*)) get_next_message_id;
3dd3c5f3
MW
1785 this->public.retransmit_request = (status_t (*) (ike_sa_t *, u_int32_t)) retransmit_request;
1786 this->public.log_status = (void (*) (ike_sa_t*,logger_t*,char*))log_status;
1787 this->public.delete = (status_t(*)(ike_sa_t*))delete_;
1788 this->public.destroy = (void(*)(ike_sa_t*))destroy;
1789 this->public.send_dpd = (status_t (*)(ike_sa_t*)) send_dpd;
1790 this->public.send_keepalive = (void (*)(ike_sa_t*)) send_keepalive;
1791 this->public.get_prf = (prf_t *(*) (ike_sa_t *)) get_prf;
1792 this->public.get_child_prf = (prf_t *(*) (ike_sa_t *)) get_child_prf;
1793 this->public.get_prf_auth_i = (prf_t *(*) (ike_sa_t *)) get_prf_auth_i;
1794 this->public.get_prf_auth_r = (prf_t *(*) (ike_sa_t *)) get_prf_auth_r;
3dd3c5f3 1795 this->public.build_transforms = (status_t (*) (ike_sa_t *,proposal_t*,diffie_hellman_t*,chunk_t,chunk_t,bool)) build_transforms;
698d7749 1796 this->public.add_child_sa = (void (*) (ike_sa_t*,child_sa_t*)) add_child_sa;
45f76a7d 1797 this->public.has_child_sa = (bool(*)(ike_sa_t*,u_int32_t)) has_child_sa;
698d7749
MW
1798 this->public.get_child_sa = (child_sa_t* (*)(ike_sa_t*,protocol_id_t,u_int32_t,bool)) get_child_sa;
1799 this->public.rekey_child_sa = (status_t(*)(ike_sa_t*,protocol_id_t,u_int32_t)) rekey_child_sa;
1800 this->public.delete_child_sa = (status_t(*)(ike_sa_t*,protocol_id_t,u_int32_t)) delete_child_sa;
1801 this->public.destroy_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t))destroy_child_sa;
3dd3c5f3
MW
1802 this->public.enable_natt = (void(*)(ike_sa_t*, bool)) enable_natt;
1803 this->public.is_natt_enabled = (bool(*)(ike_sa_t*)) is_natt_enabled;
1804
7ba38761 1805 /* initialize private fields */
5113680f 1806 this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
d048df5c 1807 this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
8dfbe71b 1808 this->name = strdup("(uninitialized)");
7ba38761 1809 this->child_sas = linked_list_create();
45f76a7d
MW
1810 this->my_host = host_create(AF_INET, "0.0.0.0", 0);
1811 this->other_host = host_create(AF_INET, "0.0.0.0", 0);
1812 this->my_id = identification_create_from_encoding(ID_ANY, CHUNK_INITIALIZER);
1813 this->other_id = identification_create_from_encoding(ID_ANY, CHUNK_INITIALIZER);
3dd3c5f3
MW
1814 this->crypter_in = NULL;
1815 this->crypter_out = NULL;
1816 this->signer_in = NULL;
1817 this->signer_out = NULL;
b4e3d1dd 1818 this->prf = NULL;
ce461bbd
MW
1819 this->prf_auth_i = NULL;
1820 this->prf_auth_r = NULL;
971218c3 1821 this->child_prf = NULL;
1396815a
MW
1822 this->nat_here = FALSE;
1823 this->nat_there = FALSE;
3dd3c5f3
MW
1824 this->transaction_queue = linked_list_create();
1825 this->transaction_in = NULL;
1826 this->transaction_in_next = NULL;
1827 this->transaction_out = NULL;
bcb95ced
MW
1828 this->state = IKE_CREATED;
1829 /* we start with message ID out, as ike_sa_init does not use this counter */
3dd3c5f3
MW
1830 this->message_id_out = 0;
1831 this->time_inbound = 0;
1832 this->time_outbound = 0;
1833
1834 return &this->public;
7ba38761 1835}