- refactored ike proposal
[strongswan.git] / Source / charon / sa / states / ike_sa_init_requested.c
1 /**
2 * @file ike_sa_init_requested.c
3 *
4 * @brief Implementation of ike_sa_init_requested_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include "ike_sa_init_requested.h"
24
25 #include <daemon.h>
26 #include <utils/allocator.h>
27 #include <encoding/payloads/sa_payload.h>
28 #include <encoding/payloads/ke_payload.h>
29 #include <encoding/payloads/nonce_payload.h>
30 #include <encoding/payloads/notify_payload.h>
31 #include <encoding/payloads/id_payload.h>
32 #include <encoding/payloads/auth_payload.h>
33 #include <encoding/payloads/ts_payload.h>
34 #include <transforms/diffie_hellman.h>
35 #include <sa/states/ike_auth_requested.h>
36 #include <sa/states/initiator_init.h>
37 #include <sa/authenticator.h>
38
39
40 typedef struct private_ike_sa_init_requested_t private_ike_sa_init_requested_t;
41
42 /**
43 * Private data of a ike_sa_init_requested_t object.
44 *
45 */
46 struct private_ike_sa_init_requested_t {
47 /**
48 * Public interface of an ike_sa_init_requested_t object.
49 */
50 ike_sa_init_requested_t public;
51
52 /**
53 * Assigned IKE_SA
54 */
55 protected_ike_sa_t *ike_sa;
56
57 /**
58 * Diffie Hellman object used to compute shared secret.
59 */
60 diffie_hellman_t *diffie_hellman;
61
62 /**
63 * Sent nonce value.
64 */
65 chunk_t sent_nonce;
66
67 /**
68 * Received nonce
69 */
70 chunk_t received_nonce;
71
72 /**
73 * Selected proposal
74 */
75 proposal_t *proposal;
76
77 /**
78 * Packet data of ike_sa_init request
79 */
80 chunk_t ike_sa_init_request_data;
81
82 /**
83 * Assigned logger
84 *
85 * Is logger of ike_sa!
86 */
87 logger_t *logger;
88
89
90 /**
91 * Process NONCE payload of IKE_SA_INIT response.
92 *
93 * @param this calling object
94 * @param nonce_payload NONCE payload to process
95 * @return SUCCESS in any case
96 */
97 status_t (*process_nonce_payload) (private_ike_sa_init_requested_t *this, nonce_payload_t *nonce_payload);
98
99 /**
100 * Process SA payload of IKE_SA_INIT response.
101 *
102 * @param this calling object
103 * @param sa_payload SA payload to process
104 * @return
105 * - SUCCESS
106 * - FAILED
107 */
108 status_t (*process_sa_payload) (private_ike_sa_init_requested_t *this, sa_payload_t *sa_payload);
109
110 /**
111 * Process KE payload of IKE_SA_INIT response.
112 *
113 * @param this calling object
114 * @param sa_payload KE payload to process
115 * @return
116 * - SUCCESS
117 * - FAILED
118 */
119 status_t (*process_ke_payload) (private_ike_sa_init_requested_t *this, ke_payload_t *ke_payload);
120
121 /**
122 * Build ID payload for IKE_AUTH request.
123 *
124 * @param this calling object
125 * @param[out] id_payload buildet ID payload
126 * @param response created payload will be added to this message_t object
127 * @return
128 * - SUCCESS
129 * - FAILED
130 */
131 status_t (*build_id_payload) (private_ike_sa_init_requested_t *this,id_payload_t **id_payload, message_t *response);
132
133 /**
134 * Build AUTH payload for IKE_AUTH request.
135 *
136 * @param this calling object
137 * @param my_id_payload buildet ID payload
138 * @param response created payload will be added to this message_t object
139 * @return
140 * - SUCCESS
141 * - FAILED
142 */
143 status_t (*build_auth_payload) (private_ike_sa_init_requested_t *this,id_payload_t *my_id_payload, message_t *response);
144
145 /**
146 * Build SA payload for IKE_AUTH request.
147 *
148 * @param this calling object
149 * @param response created payload will be added to this message_t object
150 * @return
151 * - SUCCESS
152 * - FAILED
153 */
154 status_t (*build_sa_payload) (private_ike_sa_init_requested_t *this, message_t *response);
155
156 /**
157 * Build TSi payload for IKE_AUTH request.
158 *
159 * @param this calling object
160 * @param response created payload will be added to this message_t object
161 * @return
162 * - SUCCESS
163 * - FAILED
164 */
165 status_t (*build_tsi_payload) (private_ike_sa_init_requested_t *this, message_t *response);
166
167 /**
168 * Build TSr payload for IKE_AUTH request.
169 *
170 * @param this calling object
171 * @param response created payload will be added to this message_t object
172 * @return
173 * - SUCCESS
174 * - FAILED
175 */
176 status_t (*build_tsr_payload) (private_ike_sa_init_requested_t *this, message_t *response);
177
178 /**
179 * Process a notify payload and react.
180 *
181 * @param this calling object
182 * @param notify_payload notify_payload to handle
183 */
184 status_t (*process_notify_payload) (private_ike_sa_init_requested_t *this, notify_payload_t *notify_payload);
185
186 /**
187 * Destroy function called internally of this class after state change to
188 * state IKE_AUTH_REQUESTED succeeded.
189 *
190 * In case of state change to INITIATOR_INIT the default destroy function gets called.
191 *
192 * This destroy function does not destroy objects which were passed to the new state.
193 *
194 * @param this calling object
195 */
196 void (*destroy_after_state_change) (private_ike_sa_init_requested_t *this);
197 };
198
199 /**
200 * Implementation of state_t.process_message.
201 */
202 static status_t process_message(private_ike_sa_init_requested_t *this, message_t *ike_sa_init_reply)
203 {
204 ike_auth_requested_t *next_state;
205 chunk_t ike_sa_init_reply_data;
206 sa_payload_t *sa_payload = NULL;
207 ke_payload_t *ke_payload = NULL;
208 id_payload_t *id_payload = NULL;
209 nonce_payload_t *nonce_payload = NULL;
210 u_int64_t responder_spi;
211 ike_sa_id_t *ike_sa_id;
212 iterator_t *payloads;
213
214 message_t *request;
215 status_t status;
216
217 /*
218 * In this state a reply message of type IKE_SA_INIT is expected:
219 *
220 * <-- HDR, SAr1, KEr, Nr, [CERTREQ]
221 * or
222 * <-- HDR, N
223 */
224
225 if (ike_sa_init_reply->get_exchange_type(ike_sa_init_reply) != IKE_SA_INIT)
226 {
227 this->logger->log(this->logger, ERROR | LEVEL1, "Message of type %s not supported in state ike_sa_init_requested",
228 mapping_find(exchange_type_m,ike_sa_init_reply->get_exchange_type(ike_sa_init_reply)));
229 return FAILED;
230 }
231
232 if (ike_sa_init_reply->get_request(ike_sa_init_reply))
233 {
234 this->logger->log(this->logger, ERROR | LEVEL1, "IKE_SA_INIT requests not allowed state ike_sa_init_responded");
235 return FAILED;
236 }
237
238 /* parse incoming message */
239 status = ike_sa_init_reply->parse_body(ike_sa_init_reply, NULL, NULL);
240 if (status != SUCCESS)
241 {
242 this->logger->log(this->logger, ERROR | LEVEL1, "IKE_SA_INIT reply parsing faild. Ignoring message");
243 return status;
244 }
245
246 /* because we are original initiator we have to update the responder SPI to the new one */
247 responder_spi = ike_sa_init_reply->get_responder_spi(ike_sa_init_reply);
248 if (responder_spi == 0)
249 {
250 this->logger->log(this->logger, ERROR | LEVEL1, "IKE_SA_INIT reply contained a SPI of zero");
251 return FAILED;
252 }
253 ike_sa_id = this->ike_sa->public.get_id(&(this->ike_sa->public));
254 ike_sa_id->set_responder_spi(ike_sa_id,responder_spi);
255
256 /* Iterate over all payloads.
257 *
258 * The message is allready checked for the right payload types.
259 */
260 payloads = ike_sa_init_reply->get_payload_iterator(ike_sa_init_reply);
261 while (payloads->has_next(payloads))
262 {
263 payload_t *payload;
264 payloads->current(payloads, (void**)&payload);
265
266 switch (payload->get_type(payload))
267 {
268 case SECURITY_ASSOCIATION:
269 {
270 sa_payload = (sa_payload_t*)payload;
271 break;
272 }
273 case KEY_EXCHANGE:
274 {
275 ke_payload = (ke_payload_t*)payload;
276 break;
277 }
278 case NONCE:
279 {
280 nonce_payload = (nonce_payload_t*)payload;
281 break;
282 }
283 case NOTIFY:
284 {
285 notify_payload_t *notify_payload = (notify_payload_t *) payload;
286
287 status = this->process_notify_payload(this, notify_payload);
288 if (status != SUCCESS)
289 {
290 payloads->destroy(payloads);
291 return status;
292 }
293 }
294 default:
295 {
296 this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring payload %s (%d)",
297 mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
298 break;
299 }
300
301 }
302
303 }
304 payloads->destroy(payloads);
305
306 if (!(nonce_payload && sa_payload && ke_payload))
307 {
308 this->logger->log(this->logger, AUDIT, "IKE_SA_INIT reply did not contain all required payloads. Deleting IKE_SA");
309 return DELETE_ME;
310 }
311
312 status = this->process_nonce_payload (this,nonce_payload);
313 if (status != SUCCESS)
314 {
315 return status;
316 }
317
318 status = this->process_sa_payload (this,sa_payload);
319 if (status != SUCCESS)
320 {
321 return status;
322 }
323
324 status = this->process_ke_payload (this,ke_payload);
325 if (status != SUCCESS)
326 {
327 return status;
328 }
329
330 /* derive all the keys used in the IKE_SA */
331 status = this->ike_sa->build_transforms(this->ike_sa, this->proposal, this->diffie_hellman, this->sent_nonce, this->received_nonce);
332 if (status != SUCCESS)
333 {
334 this->logger->log(this->logger, AUDIT, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
335 return DELETE_ME;
336 }
337
338 /* build empty message */
339 this->ike_sa->build_message(this->ike_sa, IKE_AUTH, TRUE, &request);
340
341 status = this->build_id_payload(this, &id_payload,request);
342 if (status != SUCCESS)
343 {
344 request->destroy(request);
345 return status;
346 }
347 status = this->build_auth_payload(this,(id_payload_t *) id_payload, request);
348 if (status != SUCCESS)
349 {
350 request->destroy(request);
351 return status;
352 }
353 status = this->build_sa_payload(this, request);
354 if (status != SUCCESS)
355 {
356 request->destroy(request);
357 return status;
358 }
359 status = this->build_tsi_payload(this, request);
360 if (status != SUCCESS)
361 {
362 request->destroy(request);
363 return status;
364 }
365 status = this->build_tsr_payload(this, request);
366 if (status != SUCCESS)
367 {
368 request->destroy(request);
369 return status;
370 }
371
372 /* message can now be sent (must not be destroyed) */
373 status = this->ike_sa->send_request(this->ike_sa, request);
374 if (status != SUCCESS)
375 {
376 this->logger->log(this->logger, AUDIT, "Unable to send IKE_AUTH request. Deleting IKE_SA");
377 request->destroy(request);
378 return DELETE_ME;
379 }
380
381 this->ike_sa->set_last_replied_message_id(this->ike_sa,ike_sa_init_reply->get_message_id(ike_sa_init_reply));
382
383 ike_sa_init_reply_data = ike_sa_init_reply->get_packet_data(ike_sa_init_reply);
384
385 /* state can now be changed */
386 next_state = ike_auth_requested_create(this->ike_sa,this->sent_nonce,this->received_nonce,ike_sa_init_reply_data);
387 this->ike_sa->set_new_state(this->ike_sa,(state_t *) next_state);
388
389 this->destroy_after_state_change(this);
390 return SUCCESS;
391 }
392
393
394 /**
395 * Implementation of private_ike_sa_init_requested_t.process_nonce_payload.
396 */
397 status_t process_nonce_payload (private_ike_sa_init_requested_t *this, nonce_payload_t *nonce_payload)
398 {
399 allocator_free(this->received_nonce.ptr);
400 this->received_nonce = nonce_payload->get_nonce(nonce_payload);
401 return SUCCESS;
402 }
403
404
405 /**
406 * Implementation of private_ike_sa_init_requested_t.process_sa_payload.
407 */
408 status_t process_sa_payload (private_ike_sa_init_requested_t *this, sa_payload_t *sa_payload)
409 {
410 proposal_t *proposal;
411 linked_list_t *proposal_list;
412 init_config_t *init_config;
413
414 init_config = this->ike_sa->get_init_config(this->ike_sa);
415
416 /* get the list of selected proposals, the peer has to select only one proposal */
417 proposal_list = sa_payload->get_proposals (sa_payload);
418 if (proposal_list->get_count(proposal_list) != 1)
419 {
420 this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response did not contain a single proposal. Deleting IKE_SA");
421 while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
422 {
423 proposal->destroy(proposal);
424 }
425 proposal_list->destroy(proposal_list);
426 return DELETE_ME;
427 }
428
429 /* we have to re-check if the others selection is valid */
430 this->proposal = init_config->select_proposal(init_config, proposal_list);
431 while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
432 {
433 proposal->destroy(proposal);
434 }
435 proposal_list->destroy(proposal_list);
436
437 if (this->proposal == NULL)
438 {
439 this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response contained selected proposal we did not offer. Deleting IKE_SA");
440 return DELETE_ME;
441 }
442
443 return SUCCESS;
444 }
445
446 /**
447 * Implementation of private_ike_sa_init_requested_t.process_ke_payload.
448 */
449 status_t process_ke_payload (private_ike_sa_init_requested_t *this, ke_payload_t *ke_payload)
450 {
451 this->diffie_hellman->set_other_public_value(this->diffie_hellman, ke_payload->get_key_exchange_data(ke_payload));
452
453 return SUCCESS;
454 }
455
456 /**
457 * Implementation of private_ike_sa_init_requested_t.build_id_payload.
458 */
459 static status_t build_id_payload (private_ike_sa_init_requested_t *this,id_payload_t **id_payload, message_t *request)
460 {
461 sa_config_t *sa_config;
462 id_payload_t *new_id_payload;
463 identification_t *identification;
464
465 sa_config = this->ike_sa->get_sa_config(this->ike_sa);
466 /* identification_t object gets NOT cloned here */
467 identification = sa_config->get_my_id(sa_config);
468 new_id_payload = id_payload_create_from_identification(TRUE,identification);
469
470 this->logger->log(this->logger, CONTROL|LEVEL2, "Add ID payload to message");
471 request->add_payload(request,(payload_t *) new_id_payload);
472
473 *id_payload = new_id_payload;
474
475 return SUCCESS;
476 }
477
478 /**
479 * Implementation of private_ike_sa_init_requested_t.build_auth_payload.
480 */
481 static status_t build_auth_payload (private_ike_sa_init_requested_t *this, id_payload_t *my_id_payload, message_t *request)
482 {
483 authenticator_t *authenticator;
484 auth_payload_t *auth_payload;
485 status_t status;
486
487 authenticator = authenticator_create(this->ike_sa);
488 status = authenticator->compute_auth_data(authenticator,&auth_payload,this->ike_sa_init_request_data,this->received_nonce,my_id_payload,TRUE);
489 authenticator->destroy(authenticator);
490
491 if (status != SUCCESS)
492 {
493 this->logger->log(this->logger, AUDIT, "Could not generate AUTH data for IKE_AUTH request. Deleting IKE_SA");
494 return DELETE_ME;
495 }
496
497 this->logger->log(this->logger, CONTROL|LEVEL2, "Add AUTH payload to message");
498 request->add_payload(request,(payload_t *) auth_payload);
499
500 return SUCCESS;
501 }
502
503 /**
504 * Implementation of private_ike_sa_init_requested_t.build_sa_payload.
505 */
506 static status_t build_sa_payload (private_ike_sa_init_requested_t *this, message_t *request)
507 {
508 linked_list_t *proposal_list;
509 sa_payload_t *sa_payload;
510 sa_config_t *sa_config;
511
512 /* get proposals form config, add to payload */
513 sa_config = this->ike_sa->get_sa_config(this->ike_sa);
514 proposal_list = sa_config->get_proposals(sa_config);
515 sa_payload = sa_payload_create_from_proposal_list(proposal_list);
516
517 /* TODO child sa stuff */
518
519 this->logger->log(this->logger, CONTROL|LEVEL2, "Add SA payload to message");
520 request->add_payload(request,(payload_t *) sa_payload);
521
522 return SUCCESS;
523 }
524
525 /**
526 * Implementation of private_ike_sa_init_requested_t.build_tsi_payload.
527 */
528 static status_t build_tsi_payload (private_ike_sa_init_requested_t *this, message_t *request)
529 {
530 traffic_selector_t **traffic_selectors;
531 size_t traffic_selectors_count;
532 ts_payload_t *ts_payload;
533 sa_config_t *sa_config;
534
535 sa_config = this->ike_sa->get_sa_config(this->ike_sa);
536 traffic_selectors_count = sa_config->get_traffic_selectors_initiator(sa_config,&traffic_selectors);
537 ts_payload = ts_payload_create_from_traffic_selectors(TRUE,traffic_selectors, traffic_selectors_count);
538
539 /* cleanup traffic selectors */
540 while(traffic_selectors_count--)
541 {
542 traffic_selector_t *ts = *traffic_selectors + traffic_selectors_count;
543 ts->destroy(ts);
544 }
545 allocator_free(traffic_selectors);
546
547 this->logger->log(this->logger, CONTROL|LEVEL2, "Add TSi payload to message");
548 request->add_payload(request,(payload_t *) ts_payload);
549
550 return SUCCESS;
551 }
552
553 /**
554 * Implementation of private_ike_sa_init_requested_t.build_tsr_payload.
555 */
556 static status_t build_tsr_payload (private_ike_sa_init_requested_t *this, message_t *request)
557 {
558 traffic_selector_t **traffic_selectors;
559 size_t traffic_selectors_count;
560 ts_payload_t *ts_payload;
561 sa_config_t *sa_config;
562
563 sa_config = this->ike_sa->get_sa_config(this->ike_sa);
564 traffic_selectors_count = sa_config->get_traffic_selectors_responder(sa_config,&traffic_selectors);
565 ts_payload = ts_payload_create_from_traffic_selectors(FALSE,traffic_selectors, traffic_selectors_count);
566
567 /* cleanup traffic selectors */
568 while(traffic_selectors_count--)
569 {
570 traffic_selector_t *ts = *traffic_selectors + traffic_selectors_count;
571 ts->destroy(ts);
572 }
573 allocator_free(traffic_selectors);
574
575 this->logger->log(this->logger, CONTROL|LEVEL2, "Add TSr payload to message");
576 request->add_payload(request,(payload_t *) ts_payload);
577
578 return SUCCESS;
579 }
580
581 /**
582 * Implementation of private_ike_sa_init_requested_t.process_notify_payload.
583 */
584 static status_t process_notify_payload(private_ike_sa_init_requested_t *this, notify_payload_t *notify_payload)
585 {
586 notify_message_type_t notify_message_type = notify_payload->get_notify_message_type(notify_payload);
587
588 this->logger->log(this->logger, CONTROL|LEVEL1, "Process notify type %s for protocol %s",
589 mapping_find(notify_message_type_m, notify_message_type),
590 mapping_find(protocol_id_m, notify_payload->get_protocol_id(notify_payload)));
591
592 if (notify_payload->get_protocol_id(notify_payload) != IKE)
593 {
594 this->logger->log(this->logger, ERROR | LEVEL1, "Notify reply not for IKE protocol.");
595 return FAILED;
596 }
597 switch (notify_message_type)
598 {
599 case NO_PROPOSAL_CHOSEN:
600 {
601 this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response contained a NO_PROPOSAL_CHOSEN notify. Deleting IKE_SA");
602 return DELETE_ME;
603 }
604 case INVALID_MAJOR_VERSION:
605 {
606 this->logger->log(this->logger, AUDIT, "IKE_SA_INIT response contained a INVALID_MAJOR_VERSION notify. Deleting IKE_SA");
607 return DELETE_ME;
608 }
609 case INVALID_KE_PAYLOAD:
610 {
611 initiator_init_t *initiator_init_state;
612 chunk_t notify_data;
613 diffie_hellman_group_t dh_group;
614 init_config_t *init_config;
615
616 notify_data = notify_payload->get_notification_data(notify_payload);
617 dh_group = ntohs(*((u_int16_t*)notify_data.ptr));
618
619 this->logger->log(this->logger, ERROR|LEVEL1, "Peer wouldn't accept DH group, it requested %s!",
620 mapping_find(diffie_hellman_group_m, dh_group));
621 /* check if we can accept this dh group */
622 init_config = this->ike_sa->get_init_config(this->ike_sa);
623 if (!init_config->check_dh_group(init_config, dh_group))
624 {
625 this->logger->log(this->logger, AUDIT,
626 "Peer does only accept DH group %s, which we do not accept! Aborting",
627 mapping_find(diffie_hellman_group_m, dh_group));
628 return DELETE_ME;
629 }
630
631 /* Going to change state back to initiator_init_t */
632 this->logger->log(this->logger, CONTROL|LEVEL2, "Create next state object");
633 initiator_init_state = initiator_init_create(this->ike_sa);
634
635 /* buffer of sent and received messages has to get reseted */
636 this->ike_sa->reset_message_buffers(this->ike_sa);
637
638 /* state can now be changed */
639 this->ike_sa->set_new_state(this->ike_sa,(state_t *) initiator_init_state);
640
641 /* state has NOW changed :-) */
642 this->logger->log(this->logger, CONTROL|LEVEL1, "Changed state of IKE_SA from %s to %s",
643 mapping_find(ike_sa_state_m,INITIATOR_INIT), mapping_find(ike_sa_state_m,IKE_SA_INIT_REQUESTED));
644
645 this->logger->log(this->logger, CONTROL|LEVEL2, "Destroy old sate object");
646 this->logger->log(this->logger, CONTROL|LEVEL2, "Going to retry initialization of connection");
647
648 this->public.state_interface.destroy(&(this->public.state_interface));
649 if (initiator_init_state->retry_initiate_connection (initiator_init_state, dh_group) != SUCCESS)
650 {
651 return DELETE_ME;
652 }
653 return FAILED;
654 }
655 default:
656 {
657 /*
658 * - In case of unknown error: IKE_SA gets destroyed.
659 * - In case of unknown status: logging
660 */
661 if (notify_message_type < 16383)
662 {
663 this->logger->log(this->logger, AUDIT, "IKE_SA_INIT reply contained an unknown notify error (%d). Deleting IKE_SA",
664 notify_message_type);
665 return DELETE_ME;
666 }
667 else
668 {
669 this->logger->log(this->logger, CONTROL, "IKE_SA_INIT reply contained an unknown notify (%d), ignored.",
670 notify_message_type);
671 return SUCCESS;
672 }
673 }
674 }
675 }
676
677 /**
678 * Implementation of state_t.get_state.
679 */
680 static ike_sa_state_t get_state(private_ike_sa_init_requested_t *this)
681 {
682 return IKE_SA_INIT_REQUESTED;
683 }
684
685 /**
686 * Implementation of private_ike_sa_init_requested_t.destroy_after_state_change.
687 */
688 static void destroy_after_state_change (private_ike_sa_init_requested_t *this)
689 {
690 this->diffie_hellman->destroy(this->diffie_hellman);
691 allocator_free_chunk(&(this->ike_sa_init_request_data));
692 if (this->proposal)
693 {
694 this->proposal->destroy(this->proposal);
695 }
696 allocator_free(this);
697 }
698
699 /**
700 * Implementation state_t.destroy.
701 */
702 static void destroy(private_ike_sa_init_requested_t *this)
703 {
704 this->diffie_hellman->destroy(this->diffie_hellman);
705 allocator_free(this->sent_nonce.ptr);
706 allocator_free(this->received_nonce.ptr);
707 allocator_free_chunk(&(this->ike_sa_init_request_data));
708 if (this->proposal)
709 {
710 this->proposal->destroy(this->proposal);
711 }
712 allocator_free(this);
713 }
714
715 /*
716 * Described in header.
717 */
718 ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa, diffie_hellman_t *diffie_hellman, chunk_t sent_nonce,chunk_t ike_sa_init_request_data)
719 {
720 private_ike_sa_init_requested_t *this = allocator_alloc_thing(private_ike_sa_init_requested_t);
721
722 /* interface functions */
723 this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *)) process_message;
724 this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state;
725 this->public.state_interface.destroy = (void (*) (state_t *)) destroy;
726
727 /* private functions */
728 this->destroy_after_state_change = destroy_after_state_change;
729 this->process_nonce_payload = process_nonce_payload;
730 this->process_sa_payload = process_sa_payload;
731 this->process_ke_payload = process_ke_payload;
732 this->build_auth_payload = build_auth_payload;
733 this->build_tsi_payload = build_tsi_payload;
734 this->build_tsr_payload = build_tsr_payload;
735 this->build_id_payload = build_id_payload;
736 this->build_sa_payload = build_sa_payload;
737 this->process_notify_payload = process_notify_payload;
738
739 /* private data */
740 this->ike_sa = ike_sa;
741 this->received_nonce = CHUNK_INITIALIZER;
742 this->logger = this->ike_sa->get_logger(this->ike_sa);
743 this->diffie_hellman = diffie_hellman;
744 this->proposal = NULL;
745 this->sent_nonce = sent_nonce;
746 this->ike_sa_init_request_data = ike_sa_init_request_data;
747
748 return &(this->public);
749 }