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