d8f380552c9a4bbcf7f1cce87661c2c0011f2b47
[strongswan.git] / src / charon / sa / states / ike_sa_init_responded.c
1 /**
2 * @file ike_sa_init_responded.c
3 *
4 * @brief State of a IKE_SA after responding to an IKE_SA_INIT request
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
10 * Copyright (C) 2005 Jan Hutter, Martin Willi
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include <string.h>
25
26 #include "ike_sa_init_responded.h"
27
28 #include <daemon.h>
29 #include <sa/authenticator.h>
30 #include <sa/child_sa.h>
31 #include <encoding/payloads/ts_payload.h>
32 #include <encoding/payloads/sa_payload.h>
33 #include <encoding/payloads/id_payload.h>
34 #include <encoding/payloads/auth_payload.h>
35 #include <encoding/payloads/notify_payload.h>
36 #include <crypto/signers/signer.h>
37 #include <crypto/crypters/crypter.h>
38 #include <sa/states/ike_sa_established.h>
39
40
41 typedef struct private_ike_sa_init_responded_t private_ike_sa_init_responded_t;
42
43 /**
44 * Private data of a ike_sa_init_responded_t object.
45 *
46 */
47 struct private_ike_sa_init_responded_t {
48 /**
49 * Public interface of ike_sa_init_responded_t.
50 */
51 ike_sa_init_responded_t public;
52
53 /**
54 * Assigned IKE_SA.
55 */
56 protected_ike_sa_t *ike_sa;
57
58 /**
59 * Received nonce.
60 */
61 chunk_t received_nonce;
62
63 /**
64 * Sent nonce.
65 */
66 chunk_t sent_nonce;
67
68 /**
69 * Binary representation of the IKE_SA_INIT response.
70 */
71 chunk_t ike_sa_init_response_data;
72
73 /**
74 * Binary representation of the IKE_SA_INIT request.
75 */
76 chunk_t ike_sa_init_request_data;
77
78 /**
79 * SA config to use.
80 */
81 policy_t *policy;
82
83 /**
84 * CHILD_SA, if set up
85 */
86 child_sa_t *child_sa;
87
88 /**
89 * Traffic selectors applicable at our site
90 */
91 linked_list_t *my_ts;
92
93 /**
94 * Traffic selectors applicable at remote site
95 */
96 linked_list_t *other_ts;
97
98 /**
99 * Assigned logger.
100 *
101 * Is logger of ike_sa!
102 */
103 logger_t *logger;
104
105 /**
106 * Process received IDi and IDr payload and build IDr payload for IKE_AUTH response.
107 *
108 * @param this calling object
109 * @param request_idi ID payload representing initiator
110 * @param request_idr ID payload representing responder (May be zero)
111 * @param response The created IDr payload is added to this message_t object
112 * @param response_idr The created IDr payload is also written to this location
113 */
114 status_t (*build_idr_payload) (private_ike_sa_init_responded_t *this,
115 id_payload_t *request_idi,
116 id_payload_t *request_idr,
117 message_t *response,
118 id_payload_t **response_idr);
119
120 /**
121 * Process received SA payload and build SA payload for IKE_AUTH response.
122 *
123 * @param this calling object
124 * @param request SA payload received in IKE_AUTH request
125 * @param response The created SA payload is added to this message_t object
126 */
127 status_t (*build_sa_payload) (private_ike_sa_init_responded_t *this, sa_payload_t *request, message_t *response);
128
129 /**
130 * Process received AUTH payload and build AUTH payload for IKE_AUTH response.
131 *
132 * @param this calling object
133 * @param request AUTH payload received in IKE_AUTH request
134 * @param other_id_payload other ID payload needed to verify AUTH data
135 * @param my_id_payload my ID payload needed to compute AUTH data
136 * @param response The created AUTH payload is added to this message_t object
137 */
138 status_t (*build_auth_payload) (private_ike_sa_init_responded_t *this, auth_payload_t *request,id_payload_t *other_id_payload,id_payload_t *my_id_payload, message_t* response);
139
140 /**
141 * Process received TS payload and build TS payload for IKE_AUTH response.
142 *
143 * @param this calling object
144 * @param is_initiator type of TS payload. TRUE for TSi, FALSE for TSr
145 * @param request TS payload received in IKE_AUTH request
146 * @param response the created TS payload is added to this message_t object
147 */
148 status_t (*build_ts_payload) (private_ike_sa_init_responded_t *this, bool ts_initiator, ts_payload_t *request, message_t *response);
149
150 /**
151 * Sends a IKE_AUTH reply containing a notify payload.
152 *
153 * @param this calling object
154 * @param notify_payload payload to process
155 * @return
156 * - DESTROY_ME if IKE_SA should be deleted
157 * - SUCCSS if processed successfull
158 */
159 status_t (*process_notify_payload) (private_ike_sa_init_responded_t *this, notify_payload_t* notify_payload);
160
161 /**
162 * Destroy function called internally of this class after state change to
163 * state IKE_SA_ESTABLISHED succeeded.
164 *
165 * This destroy function does not destroy objects which were passed to the new state.
166 *
167 * @param this calling object
168 */
169 void (*destroy_after_state_change) (private_ike_sa_init_responded_t *this);
170 };
171
172 /**
173 * Implements state_t.get_state
174 */
175 static status_t process_message(private_ike_sa_init_responded_t *this, message_t *request)
176 {
177 id_payload_t *idi_request = NULL, *idr_request = NULL,*idr_response;
178 ts_payload_t *tsi_request = NULL, *tsr_request = NULL;
179 auth_payload_t *auth_request = NULL;
180 sa_payload_t *sa_request = NULL;
181 iterator_t *payloads;
182 message_t *response;
183 crypter_t *crypter;
184 signer_t *signer;
185 status_t status;
186 host_t *my_host, *other_host;
187 identification_t *my_id, *other_id;
188 connection_t *connection;
189 policy_t *policy;
190
191 if (request->get_exchange_type(request) != IKE_AUTH)
192 {
193 this->logger->log(this->logger, ERROR | LEVEL1, "Message of type %s not supported in state ike_sa_init_responded",
194 mapping_find(exchange_type_m,request->get_exchange_type(request)));
195 return FAILED;
196 }
197
198 if (!request->get_request(request))
199 {
200 this->logger->log(this->logger, ERROR | LEVEL1, "IKE_AUTH responses not allowed state ike_sa_init_responded");
201 return FAILED;
202 }
203
204 /* get signer for verification and crypter for decryption */
205 signer = this->ike_sa->get_signer_initiator(this->ike_sa);
206 crypter = this->ike_sa->get_crypter_initiator(this->ike_sa);
207
208 status = request->parse_body(request, crypter, signer);
209 if (status != SUCCESS)
210 {
211 if (status == NOT_SUPPORTED)
212 {
213 this->logger->log(this->logger, ERROR | LEVEL1, "IKE_AUTH request contains unsupported payload with critical flag set. "
214 "Deleting IKE_SA");
215 this->ike_sa->send_notify(this->ike_sa, IKE_AUTH, UNSUPPORTED_CRITICAL_PAYLOAD, CHUNK_INITIALIZER);
216 return DESTROY_ME;
217 }
218 else
219 {
220 this->logger->log(this->logger, AUDIT, "IKE_AUTH request decryption failed. Ignoring message");
221 }
222 return status;
223 }
224
225 /* iterate over incoming payloads. Message is verified, we can be sure there are the required payloads */
226 payloads = request->get_payload_iterator(request);
227 while (payloads->has_next(payloads))
228 {
229 payload_t *payload;
230 payloads->current(payloads, (void**)&payload);
231
232 switch (payload->get_type(payload))
233 {
234 case ID_INITIATOR:
235 {
236 idi_request = (id_payload_t*)payload;
237 break;
238 }
239 case AUTHENTICATION:
240 {
241 auth_request = (auth_payload_t*)payload;
242 break;
243 }
244 case ID_RESPONDER:
245 {
246 idr_request = (id_payload_t*)payload;
247 break;
248 }
249 case SECURITY_ASSOCIATION:
250 {
251 sa_request = (sa_payload_t*)payload;
252 break;
253 }
254 case TRAFFIC_SELECTOR_INITIATOR:
255 {
256 tsi_request = (ts_payload_t*)payload;
257 break;
258 }
259 case TRAFFIC_SELECTOR_RESPONDER:
260 {
261 tsr_request = (ts_payload_t*)payload;
262 break;
263 }
264 case NOTIFY:
265 {
266 notify_payload_t *notify_payload = (notify_payload_t *) payload;
267 status = this->process_notify_payload(this, notify_payload);
268 if (status != SUCCESS)
269 {
270 payloads->destroy(payloads);
271 return status;
272 }
273 }
274 case CERTIFICATE:
275 {
276 /* TODO handle cert payloads */
277 }
278 case CERTIFICATE_REQUEST:
279 {
280 /* TODO handle certrequest payloads */
281 }
282 default:
283 {
284 this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring payload %s (%d)",
285 mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
286 break;
287 }
288 }
289 }
290 /* iterator can be destroyed */
291 payloads->destroy(payloads);
292
293 /* check if we have all payloads */
294 if (!(idi_request && sa_request && auth_request && tsi_request && tsr_request))
295 {
296 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply did not contain all required payloads. Deleting IKE_SA");
297 return DESTROY_ME;
298 }
299
300 status = this->ike_sa->update_connection_hosts(this->ike_sa,
301 request->get_destination(request), request->get_source(request));
302 if (status != SUCCESS)
303 {
304 return status;
305 }
306
307 /* build response */
308 this->ike_sa->build_message(this->ike_sa, IKE_AUTH, FALSE, &response);
309
310 /* add payloads to it */
311 status = this->build_idr_payload(this, idi_request, idr_request, response, &idr_response);
312 if (status != SUCCESS)
313 {
314 response->destroy(response);
315 return status;
316 }
317 status = this->build_auth_payload(this, auth_request,idi_request, idr_response,response);
318 if (status != SUCCESS)
319 {
320 response->destroy(response);
321 return status;
322 }
323 status = this->build_sa_payload(this, sa_request, response);
324 if (status != SUCCESS)
325 {
326 response->destroy(response);
327 return status;
328 }
329 status = this->build_ts_payload(this, TRUE, tsi_request, response);
330 if (status != SUCCESS)
331 {
332 response->destroy(response);
333 return status;
334 }
335 status = this->build_ts_payload(this, FALSE, tsr_request, response);
336 if (status != SUCCESS)
337 {
338 response->destroy(response);
339 return status;
340 }
341
342 status = this->ike_sa->send_response(this->ike_sa, response);
343 /* message can now be sent (must not be destroyed) */
344 if (status != SUCCESS)
345 {
346 this->logger->log(this->logger, AUDIT, "Unable to send IKE_AUTH reply. Deleting IKE_SA");
347 response->destroy(response);
348 return DESTROY_ME;
349 }
350
351 /* install child SA policies */
352 if (!this->child_sa)
353 {
354 this->logger->log(this->logger, CONTROL, "Proposal negotiation failed, no CHILD_SA built");
355 }
356 else if (this->my_ts->get_count(this->my_ts) == 0 || this->other_ts->get_count(this->other_ts) == 0)
357 {
358 this->logger->log(this->logger, CONTROL, "Traffic selector negotiation failed, no CHILD_SA built");
359 this->child_sa->destroy(this->child_sa);
360 this->child_sa = NULL;
361 }
362 else
363 {
364 status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts);
365 if (status != SUCCESS)
366 {
367 this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA policy! Deleting IKE_SA");
368 return DESTROY_ME;
369 }
370 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
371 }
372
373 /* create new state */
374 this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa));
375 this->destroy_after_state_change(this);
376
377 connection = this->ike_sa->get_connection(this->ike_sa);
378 my_host = connection->get_my_host(connection);
379 other_host = connection->get_other_host(connection);
380 policy = this->ike_sa->get_policy(this->ike_sa);
381 my_id = policy->get_my_id(policy);
382 other_id = policy->get_other_id(policy);
383 this->logger->log(this->logger, AUDIT, "IKE_SA established %s[%s]...%s[%s]",
384 my_host->get_address(my_host), my_id->get_string(my_id),
385 other_host->get_address(other_host), other_id->get_string(other_id));
386
387 return SUCCESS;
388 }
389
390 /**
391 * Implementation of private_ike_sa_init_responded_t.build_idr_payload.
392 */
393 static status_t build_idr_payload(private_ike_sa_init_responded_t *this, id_payload_t *request_idi, id_payload_t *request_idr, message_t *response,id_payload_t **response_idr)
394 {
395 identification_t *other_id, *my_id;
396 id_payload_t *idr_response;
397
398 /* use others ID, an ours if peer requested one */
399 other_id = request_idi->get_identification(request_idi);
400 if (request_idr)
401 {
402 my_id = request_idr->get_identification(request_idr);
403 }
404 else
405 {
406 my_id = identification_create_from_encoding(ID_ANY, CHUNK_INITIALIZER);
407 }
408
409 /* build new sa config */
410 this->policy = charon->policies->get_policy_by_ids(charon->policies, my_id, other_id);
411 if (this->policy == NULL)
412 {
413 this->logger->log(this->logger, AUDIT, "We don't have a policy for IDs %s - %s. Deleting IKE_SA",
414 my_id->get_string(my_id), other_id->get_string(other_id));
415 my_id->destroy(my_id);
416 other_id->destroy(other_id);
417 return DESTROY_ME;
418 }
419 my_id->destroy(my_id);
420 other_id->destroy(other_id);
421
422 /* get my id from policy, which must contain a fully qualified valid id */
423 my_id = this->policy->get_my_id(this->policy);
424
425 /* update others traffic selectors with actually used address */
426 this->policy->update_my_ts(this->policy, response->get_source(response));
427 this->policy->update_other_ts(this->policy, response->get_destination(response));
428
429 /* set policy in ike_sa for other states */
430 this->ike_sa->set_policy(this->ike_sa, this->policy);
431
432 /* build response */
433 idr_response = id_payload_create_from_identification(FALSE, my_id);
434 response->add_payload(response, (payload_t*)idr_response);
435 *response_idr = idr_response;
436
437 return SUCCESS;
438 }
439
440 /**
441 * Implementation of private_ike_sa_init_responded_t.build_sa_payload.
442 */
443 static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_payload_t *request, message_t *response)
444 {
445 proposal_t *proposal, *proposal_tmp;
446 linked_list_t *proposal_list;
447 sa_payload_t *sa_response;
448 chunk_t seed;
449 prf_plus_t *prf_plus;
450 status_t status;
451 connection_t *connection;
452 policy_t *policy;
453 bool use_natt;
454
455 /* prepare reply */
456 sa_response = sa_payload_create();
457
458 /* get proposals from request, and select one with ours */
459 proposal_list = request->get_proposals(request);
460 this->logger->log(this->logger, CONTROL|LEVEL1, "Selecting proposals:");
461 proposal = this->policy->select_proposal(this->policy, proposal_list);
462 /* list is not needed anymore */
463 while (proposal_list->remove_last(proposal_list, (void**)&proposal_tmp) == SUCCESS)
464 {
465 proposal_tmp->destroy(proposal_tmp);
466 }
467 proposal_list->destroy(proposal_list);
468 /* do we have a proposal? */
469 if (proposal == NULL)
470 {
471 notify_payload_t *notify;
472 this->logger->log(this->logger, AUDIT, "IKE_AUTH request did not contain any proposals we accept. "
473 "Adding NO_PROPOSAL_CHOSEN notify");
474 /* add NO_PROPOSAL_CHOSEN and an empty SA payload */
475 notify = notify_payload_create_from_protocol_and_type(PROTO_IKE, NO_PROPOSAL_CHOSEN);
476 response->add_payload(response, (payload_t*)notify);
477 }
478 else
479 {
480 /* set up child sa */
481 seed = chunk_alloc(this->received_nonce.len + this->sent_nonce.len);
482 memcpy(seed.ptr, this->received_nonce.ptr, this->received_nonce.len);
483 memcpy(seed.ptr + this->received_nonce.len, this->sent_nonce.ptr, this->sent_nonce.len);
484 prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
485 chunk_free(&seed);
486
487 policy = this->ike_sa->get_policy(this->ike_sa);
488 connection = this->ike_sa->get_connection(this->ike_sa);
489 use_natt = this->ike_sa->public.is_any_host_behind_nat(&this->ike_sa->public);
490 this->child_sa = child_sa_create(0,
491 connection->get_my_host(connection),
492 connection->get_other_host(connection),
493 policy->get_soft_lifetime(policy),
494 policy->get_hard_lifetime(policy),
495 use_natt);
496
497 status = this->child_sa->add(this->child_sa, proposal, prf_plus);
498 prf_plus->destroy(prf_plus);
499 if (status != SUCCESS)
500 {
501 this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA");
502 /* TODO: how do we handle this cleanly? */
503 sa_response->destroy(sa_response);
504 proposal->destroy(proposal);
505 return DESTROY_ME;
506 }
507
508 /* add proposal to sa payload */
509 sa_response->add_proposal(sa_response, proposal);
510 proposal->destroy(proposal);
511 }
512 response->add_payload(response, (payload_t*)sa_response);
513 return SUCCESS;
514 }
515
516 /**
517 * Implementation of private_ike_sa_init_responded_t.build_auth_payload.
518 */
519 static status_t build_auth_payload(private_ike_sa_init_responded_t *this, auth_payload_t *auth_request,id_payload_t *other_id_payload,id_payload_t *my_id_payload, message_t* response)
520 {
521 authenticator_t *authenticator;
522 auth_payload_t *auth_reply;
523 status_t status;
524
525 authenticator = authenticator_create(this->ike_sa);
526 status = authenticator->verify_auth_data(authenticator,auth_request, this->ike_sa_init_request_data,this->sent_nonce,other_id_payload,TRUE);
527
528 if (status != SUCCESS)
529 {
530 this->logger->log(this->logger, AUDIT, "IKE_AUTH request verification failed. Deleting IKE_SA");
531 this->ike_sa->send_notify(this->ike_sa, IKE_AUTH, AUTHENTICATION_FAILED, CHUNK_INITIALIZER);
532 authenticator->destroy(authenticator);
533 return DESTROY_ME;
534 }
535
536 status = authenticator->compute_auth_data(authenticator,&auth_reply, this->ike_sa_init_response_data,this->received_nonce,my_id_payload,FALSE);
537 authenticator->destroy(authenticator);
538 if (status != SUCCESS)
539 {
540 this->logger->log(this->logger, AUDIT, "Unable to build authentication data for IKE_AUTH reply. Deleting IKE_SA");
541 return DESTROY_ME;
542 }
543
544 response->add_payload(response, (payload_t *)auth_reply);
545 return SUCCESS;
546 }
547
548 /**
549 * Implementation of private_ike_sa_init_responded_t.build_ts_payload.
550 */
551 static status_t build_ts_payload(private_ike_sa_init_responded_t *this, bool ts_initiator, ts_payload_t *request, message_t* response)
552 {
553 linked_list_t *ts_received, *ts_selected;
554 traffic_selector_t *ts;
555 status_t status = SUCCESS;
556 ts_payload_t *ts_response;
557
558 /* build a reply payload with selected traffic selectors */
559 ts_received = request->get_traffic_selectors(request);
560 /* select ts depending on payload type */
561 if (ts_initiator)
562 {
563 ts_selected = this->policy->select_other_traffic_selectors(this->policy, ts_received);
564 this->other_ts = ts_selected;
565 }
566 else
567 {
568 ts_selected = this->policy->select_my_traffic_selectors(this->policy, ts_received);
569 this->my_ts = ts_selected;
570 }
571
572 ts_response = ts_payload_create_from_traffic_selectors(ts_initiator, ts_selected);
573 response->add_payload(response, (payload_t*)ts_response);
574
575 /* add notify if traffic selectors do not match */
576 if (!ts_initiator &&
577 (ts_selected->get_count(ts_selected) == 0 || this->other_ts->get_count(this->other_ts) == 0))
578 {
579 notify_payload_t *notify;
580
581 this->logger->log(this->logger, AUDIT, "IKE_AUTH request did not contain any traffic selectors we accept. "
582 "Adding TS_UNACCEPTABLE notify");
583
584 notify = notify_payload_create_from_protocol_and_type(0, TS_UNACCEPTABLE);
585 response->add_payload(response, (payload_t*)notify);
586 }
587
588 /* cleanup */
589 while (ts_received->remove_last(ts_received, (void**)&ts) == SUCCESS)
590 {
591 ts->destroy(ts);
592 }
593 ts_received->destroy(ts_received);
594
595 return status;
596 }
597
598 static status_t process_notify_payload(private_ike_sa_init_responded_t *this, notify_payload_t *notify_payload)
599 {
600 notify_message_type_t notify_message_type = notify_payload->get_notify_message_type(notify_payload);
601
602 this->logger->log(this->logger, CONTROL|LEVEL1, "Process notify type %s",
603 mapping_find(notify_message_type_m, notify_message_type));
604
605 switch (notify_message_type)
606 {
607 case SET_WINDOW_SIZE:
608 /*
609 * TODO Increase window size.
610 */
611 case INITIAL_CONTACT:
612 /*
613 * TODO Delete existing IKE_SA's with other Identity.
614 */
615 default:
616 {
617 this->logger->log(this->logger, AUDIT, "IKE_AUTH request contained an unknown notify (%d), ignored.", notify_message_type);
618 }
619 }
620
621 return SUCCESS;
622 }
623
624 /**
625 * Implementation of state_t.get_state.
626 */
627 static ike_sa_state_t get_state(private_ike_sa_init_responded_t *this)
628 {
629 return IKE_SA_INIT_RESPONDED;
630 }
631
632 /**
633 * Implementation of state_t.destroy.
634 */
635 static void destroy(private_ike_sa_init_responded_t *this)
636 {
637 chunk_free(&(this->received_nonce));
638 chunk_free(&(this->sent_nonce));
639 chunk_free(&(this->ike_sa_init_response_data));
640 chunk_free(&(this->ike_sa_init_request_data));
641 if (this->my_ts)
642 {
643 traffic_selector_t *ts;
644 while (this->my_ts->remove_last(this->my_ts, (void**)&ts) == SUCCESS)
645 {
646 ts->destroy(ts);
647 }
648 this->my_ts->destroy(this->my_ts);
649 }
650 if (this->other_ts)
651 {
652 traffic_selector_t *ts;
653 while (this->other_ts->remove_last(this->other_ts, (void**)&ts) == SUCCESS)
654 {
655 ts->destroy(ts);
656 }
657 this->other_ts->destroy(this->other_ts);
658 }
659 if (this->child_sa)
660 {
661 this->child_sa->destroy(this->child_sa);
662 }
663
664 free(this);
665 }
666 /**
667 * Implementation of private_ike_sa_init_responded.destroy_after_state_change.
668 */
669 static void destroy_after_state_change(private_ike_sa_init_responded_t *this)
670 {
671 chunk_free(&(this->received_nonce));
672 chunk_free(&(this->sent_nonce));
673 chunk_free(&(this->ike_sa_init_response_data));
674 chunk_free(&(this->ike_sa_init_request_data));
675 if (this->my_ts)
676 {
677 traffic_selector_t *ts;
678 while (this->my_ts->remove_last(this->my_ts, (void**)&ts) == SUCCESS)
679 {
680 ts->destroy(ts);
681 }
682 this->my_ts->destroy(this->my_ts);
683 }
684 if (this->other_ts)
685 {
686 traffic_selector_t *ts;
687 while (this->other_ts->remove_last(this->other_ts, (void**)&ts) == SUCCESS)
688 {
689 ts->destroy(ts);
690 }
691 this->other_ts->destroy(this->other_ts);
692 }
693
694 free(this);
695 }
696
697 /*
698 * Described in header.
699 */
700 ike_sa_init_responded_t *ike_sa_init_responded_create(protected_ike_sa_t *ike_sa, chunk_t received_nonce, chunk_t sent_nonce,chunk_t ike_sa_init_request_data, chunk_t ike_sa_init_response_data)
701 {
702 private_ike_sa_init_responded_t *this = malloc_thing(private_ike_sa_init_responded_t);
703
704 /* interface functions */
705 this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *)) process_message;
706 this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state;
707 this->public.state_interface.destroy = (void (*) (state_t *)) destroy;
708
709 /* private functions */
710 this->build_idr_payload = build_idr_payload;
711 this->build_sa_payload = build_sa_payload;
712 this->build_auth_payload = build_auth_payload;
713 this->build_ts_payload = build_ts_payload;
714 this->process_notify_payload = process_notify_payload;
715 this->destroy_after_state_change = destroy_after_state_change;
716
717 /* private data */
718 this->ike_sa = ike_sa;
719 this->received_nonce = received_nonce;
720 this->sent_nonce = sent_nonce;
721 this->ike_sa_init_response_data = ike_sa_init_response_data;
722 this->ike_sa_init_request_data = ike_sa_init_request_data;
723 this->my_ts = NULL;
724 this->other_ts = NULL;
725 this->child_sa = NULL;
726 this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
727
728 return &(this->public);
729 }