moved auth_method to policy
[strongswan.git] / src / charon / sa / transactions / ike_auth.c
1 /**
2 * @file ike_auth.c
3 *
4 * @brief Implementation of ike_auth_t transaction.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
10 * Copyright (C) 2005-2006 Martin Willi
11 * Copyright (C) 2005 Jan Hutter
12 * Hochschule fuer Technik Rapperswil
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 */
24
25 #include "ike_auth.h"
26
27 #include <string.h>
28
29 #include <daemon.h>
30 #include <encoding/payloads/sa_payload.h>
31 #include <encoding/payloads/id_payload.h>
32 #include <encoding/payloads/cert_payload.h>
33 #include <encoding/payloads/certreq_payload.h>
34 #include <encoding/payloads/auth_payload.h>
35 #include <encoding/payloads/ts_payload.h>
36 #include <sa/authenticator.h>
37 #include <sa/child_sa.h>
38
39
40 typedef struct private_ike_auth_t private_ike_auth_t;
41
42 /**
43 * Private members of a ike_auth_t object..
44 */
45 struct private_ike_auth_t {
46
47 /**
48 * Public methods and transaction_t interface.
49 */
50 ike_auth_t public;
51
52 /**
53 * Assigned IKE_SA.
54 */
55 ike_sa_t *ike_sa;
56
57 /**
58 * Message sent by our peer, if already generated
59 */
60 message_t *message;
61
62 /**
63 * Message ID this transaction uses
64 */
65 u_int32_t message_id;
66
67 /**
68 * Times we did send the request
69 */
70 u_int32_t requested;
71
72 /**
73 * initiator chosen nonce
74 */
75 chunk_t nonce_i;
76
77 /**
78 * responder chosen nonce
79 */
80 chunk_t nonce_r;
81
82 /**
83 * encoded request message of ike_sa_init transaction
84 */
85 chunk_t init_request;
86
87 /**
88 * encoded response message of ike_sa_init transaction
89 */
90 chunk_t init_response;
91
92 /**
93 * connection definition used for IKE_SA setup
94 */
95 connection_t *connection;
96
97 /**
98 * policy definition used CHILD_SA creation
99 */
100 policy_t *policy;
101
102 /**
103 * Negotiated proposal used for CHILD_SA
104 */
105 proposal_t *proposal;
106
107 /**
108 * Negotiated traffic selectors for initiator
109 */
110 linked_list_t *tsi;
111
112 /**
113 * Negotiated traffic selectors for responder
114 */
115 linked_list_t *tsr;
116
117 /**
118 * CHILD_SA created along with IKE_AUTH
119 */
120 child_sa_t *child_sa;
121
122 /**
123 * did other peer create a CHILD_SA?
124 */
125 bool build_child;
126
127 /**
128 * reqid to use for CHILD_SA setup
129 */
130 u_int32_t reqid;
131
132 /**
133 * Assigned logger.
134 */
135 logger_t *logger;
136 };
137
138 /**
139 * Implementation of transaction_t.get_message_id.
140 */
141 static u_int32_t get_message_id(private_ike_auth_t *this)
142 {
143 return this->message_id;
144 }
145
146 /**
147 * Implementation of transaction_t.requested.
148 */
149 static u_int32_t requested(private_ike_auth_t *this)
150 {
151 return this->requested++;
152 }
153
154 /**
155 * Implementation of transaction_t.set_config.
156 */
157 static void set_config(private_ike_auth_t *this,
158 connection_t *connection, policy_t *policy)
159 {
160 this->connection = connection;
161 this->policy = policy;
162 }
163
164 /**
165 * Implementation of transaction_t.set_reqid.
166 */
167 static void set_reqid(private_ike_auth_t *this, u_int32_t reqid)
168 {
169 this->reqid = reqid;
170 }
171
172 /**
173 * Implementation of transaction_t.set_nonces.
174 */
175 static void set_nonces(private_ike_auth_t *this, chunk_t nonce_i, chunk_t nonce_r)
176 {
177 this->nonce_i = nonce_i;
178 this->nonce_r = nonce_r;
179 }
180
181 /**
182 * Implementation of transaction_t.set_init_messages.
183 */
184 static void set_init_messages(private_ike_auth_t *this, chunk_t init_request, chunk_t init_response)
185 {
186 this->init_request = init_request;
187 this->init_response = init_response;
188 }
189
190 /**
191 * destroy a list of traffic selectors
192 */
193 static void destroy_ts_list(linked_list_t *list)
194 {
195 if (list)
196 {
197 traffic_selector_t *ts;
198
199 while (list->remove_last(list, (void**)&ts) == SUCCESS)
200 {
201 ts->destroy(ts);
202 }
203 list->destroy(list);
204 }
205 }
206
207 /**
208 * destroy a list of proposals
209 */
210 static void destroy_proposal_list(linked_list_t *list)
211 {
212 proposal_t *proposal;
213
214 while (list->remove_last(list, (void**)&proposal) == SUCCESS)
215 {
216 proposal->destroy(proposal);
217 }
218 list->destroy(list);
219 }
220
221 /**
222 * Implementation of transaction_t.get_request.
223 */
224 static status_t get_request(private_ike_auth_t *this, message_t **result)
225 {
226 message_t *request;
227 host_t *me, *other;
228 identification_t *my_id, *other_id;
229 id_payload_t *my_id_payload;
230
231 /* check if we already have built a message (retransmission) */
232 if (this->message)
233 {
234 *result = this->message;
235 return SUCCESS;
236 }
237
238 me = this->ike_sa->get_my_host(this->ike_sa);
239 other = this->ike_sa->get_other_host(this->ike_sa);
240 my_id = this->policy->get_my_id(this->policy);
241 other_id = this->policy->get_other_id(this->policy);
242
243 /* build the request */
244 request = message_create();
245 request->set_source(request, me->clone(me));
246 request->set_destination(request, other->clone(other));
247 request->set_exchange_type(request, IKE_AUTH);
248 request->set_request(request, TRUE);
249 request->set_ike_sa_id(request, this->ike_sa->get_id(this->ike_sa));
250 /* apply for caller */
251 *result = request;
252 /* store for retransmission */
253 this->message = request;
254
255 { /* build ID payload */
256 my_id_payload = id_payload_create_from_identification(TRUE, my_id);
257 request->add_payload(request, (payload_t*)my_id_payload);
258 }
259
260 { /* TODO: build certreq payload */
261
262 }
263
264 /* build certificate payload. TODO: Handle certreq from init_ike_sa. */
265 if (this->policy->get_auth_method(this->policy) == RSA_DIGITAL_SIGNATURE
266 && this->connection->get_cert_policy(this->connection) != CERT_NEVER_SEND)
267 {
268 cert_payload_t *cert_payload;
269
270 x509_t *cert = charon->credentials->get_certificate(charon->credentials, my_id);
271
272 if (cert)
273 {
274 cert_payload = cert_payload_create_from_x509(cert);
275 request->add_payload(request, (payload_t*)cert_payload);
276 }
277 else
278 {
279 this->logger->log(this->logger, ERROR,
280 "could not find my certificate, certificate payload omitted");
281 }
282 }
283
284 { /* build IDr payload, if other_id defined */
285 id_payload_t *id_payload;
286 if (!other_id->contains_wildcards(other_id))
287 {
288 id_payload = id_payload_create_from_identification(FALSE, other_id);
289 request->add_payload(request, (payload_t*)id_payload);
290 }
291 }
292
293 { /* build auth payload */
294 authenticator_t *authenticator;
295 auth_payload_t *auth_payload;
296 auth_method_t auth_method;
297 status_t status;
298
299 auth_method = this->policy->get_auth_method(this->policy);
300 authenticator = authenticator_create(this->ike_sa, auth_method);
301 status = authenticator->compute_auth_data(authenticator,
302 &auth_payload,
303 this->init_request,
304 this->nonce_r,
305 my_id,
306 other_id,
307 TRUE);
308 authenticator->destroy(authenticator);
309 if (status != SUCCESS)
310 {
311 this->logger->log(this->logger, AUDIT,
312 "could not generate AUTH data, deleting IKE_SA");
313 return DESTROY_ME;
314 }
315 request->add_payload(request, (payload_t*)auth_payload);
316 }
317
318 { /* build SA payload for CHILD_SA */
319 linked_list_t *proposal_list;
320 sa_payload_t *sa_payload;
321 u_int32_t soft_lifetime, hard_lifetime;
322 bool enable_natt;
323
324 proposal_list = this->policy->get_proposals(this->policy);
325 soft_lifetime = this->policy->get_soft_lifetime(this->policy);
326 hard_lifetime = this->policy->get_hard_lifetime(this->policy);
327 enable_natt = this->ike_sa->is_natt_enabled(this->ike_sa);
328 this->child_sa = child_sa_create(this->reqid, me, other, my_id, other_id,
329 soft_lifetime, hard_lifetime,
330 this->policy->get_updown(this->policy),
331 this->policy->get_hostaccess(this->policy),
332 enable_natt);
333 this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
334 if (this->child_sa->alloc(this->child_sa, proposal_list) != SUCCESS)
335 {
336 this->logger->log(this->logger, ERROR,
337 "could not install CHILD_SA, deleting IKE_SA");
338 return DESTROY_ME;
339 }
340 sa_payload = sa_payload_create_from_proposal_list(proposal_list);
341 destroy_proposal_list(proposal_list);
342 request->add_payload(request, (payload_t*)sa_payload);
343 }
344
345 { /* build TSi payload */
346 linked_list_t *ts_list;
347 ts_payload_t *ts_payload;
348
349 ts_list = this->policy->get_my_traffic_selectors(this->policy, me);
350 ts_payload = ts_payload_create_from_traffic_selectors(TRUE, ts_list);
351 destroy_ts_list(ts_list);
352
353 request->add_payload(request, (payload_t*)ts_payload);
354 }
355
356 { /* build TSr payload */
357 linked_list_t *ts_list;
358 ts_payload_t *ts_payload;
359
360 ts_list = this->policy->get_other_traffic_selectors(this->policy, other);
361 ts_payload = ts_payload_create_from_traffic_selectors(FALSE, ts_list);
362 destroy_ts_list(ts_list);
363
364 request->add_payload(request, (payload_t*)ts_payload);
365 }
366
367 this->message_id = this->ike_sa->get_next_message_id(this->ike_sa);
368 request->set_message_id(request, this->message_id);
369 return SUCCESS;
370 }
371
372 /**
373 * Handle all kind of notifies
374 */
375 static status_t process_notifies(private_ike_auth_t *this, notify_payload_t *notify_payload)
376 {
377 notify_type_t notify_type = notify_payload->get_notify_type(notify_payload);
378
379 this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
380 mapping_find(notify_type_m, notify_type));
381
382 switch (notify_type)
383 {
384 /* these notifies are not critical. no child_sa is built, but IKE stays alive */
385 case SINGLE_PAIR_REQUIRED:
386 {
387 this->logger->log(this->logger, AUDIT,
388 "received a SINGLE_PAIR_REQUIRED notify");
389 this->build_child = FALSE;
390 return SUCCESS;
391 }
392 case TS_UNACCEPTABLE:
393 {
394 this->logger->log(this->logger, CONTROL,
395 "received TS_UNACCEPTABLE notify");
396 this->build_child = FALSE;
397 return SUCCESS;
398 }
399 case NO_PROPOSAL_CHOSEN:
400 {
401 this->logger->log(this->logger, CONTROL,
402 "received NO_PROPOSAL_CHOSEN notify");
403 this->build_child = FALSE;
404 return SUCCESS;
405 }
406 default:
407 {
408 if (notify_type < 16383)
409 {
410 this->logger->log(this->logger, AUDIT,
411 "received %s notify error (%d), deleting IKE_SA",
412 mapping_find(notify_type_m, notify_type),
413 notify_type);
414 return DESTROY_ME;
415 }
416 else
417 {
418 this->logger->log(this->logger, CONTROL,
419 "received %s notify (%d), ignored",
420 mapping_find(notify_type_m, notify_type),
421 notify_type);
422 return SUCCESS;
423 }
424 }
425 }
426 }
427
428 /**
429 * Build a notify message.
430 */
431 static void build_notify(notify_type_t type, message_t *message, bool flush_message)
432 {
433 notify_payload_t *notify;
434
435 if (flush_message)
436 {
437 payload_t *payload;
438 iterator_t *iterator = message->get_payload_iterator(message);
439 while (iterator->iterate(iterator, (void**)&payload))
440 {
441 payload->destroy(payload);
442 iterator->remove(iterator);
443 }
444 iterator->destroy(iterator);
445 }
446
447 notify = notify_payload_create();
448 notify->set_notify_type(notify, type);
449 message->add_payload(message, (payload_t*)notify);
450 }
451
452 /**
453 * Import a certificate from a cert payload
454 */
455 static void import_certificate(private_ike_auth_t *this, cert_payload_t *cert_payload)
456 {
457 bool found;
458 x509_t *cert;
459 cert_encoding_t encoding;
460
461 encoding = cert_payload->get_cert_encoding(cert_payload);
462 if (encoding != CERT_X509_SIGNATURE)
463 {
464 this->logger->log(this->logger, ERROR,
465 "certificate payload %s not supported, ignored",
466 enum_name(&cert_encoding_names, encoding));
467 return;
468 }
469 cert = x509_create_from_chunk(cert_payload->get_data_clone(cert_payload));
470 if (cert)
471 {
472 if (charon->credentials->verify(charon->credentials, cert, &found))
473 {
474 this->logger->log(this->logger, CONTROL|LEVEL1,
475 "received end entity certificate is trusted, added to store");
476 if (!found)
477 {
478 charon->credentials->add_end_certificate(charon->credentials, cert);
479 }
480 else
481 {
482 cert->destroy(cert);
483 }
484 }
485 else
486 {
487 this->logger->log(this->logger, CONTROL,
488 "received end entity certificate is not trusted, discarded");
489 cert->destroy(cert);
490 }
491 }
492 else
493 {
494 this->logger->log(this->logger, CONTROL,
495 "parsing of received certificate failed, discarded");
496 }
497 }
498
499 /**
500 * Install a CHILD_SA for usage
501 */
502 static status_t install_child_sa(private_ike_auth_t *this, bool initiator)
503 {
504 prf_plus_t *prf_plus;
505 chunk_t seed;
506 status_t status;
507
508 seed = chunk_alloc(this->nonce_i.len + this->nonce_r.len);
509 memcpy(seed.ptr, this->nonce_i.ptr, this->nonce_i.len);
510 memcpy(seed.ptr + this->nonce_i.len, this->nonce_r.ptr, this->nonce_r.len);
511 prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
512 chunk_free(&seed);
513
514 if (initiator)
515 {
516 status = this->child_sa->update(this->child_sa, this->proposal, prf_plus);
517 }
518 else
519 {
520 status = this->child_sa->add(this->child_sa, this->proposal, prf_plus);
521 }
522 prf_plus->destroy(prf_plus);
523 if (status != SUCCESS)
524 {
525 return DESTROY_ME;
526 }
527 if (initiator)
528 {
529 status = this->child_sa->add_policies(this->child_sa, this->tsi, this->tsr);
530 }
531 else
532 {
533 status = this->child_sa->add_policies(this->child_sa, this->tsr, this->tsi);
534 }
535 if (status != SUCCESS)
536 {
537 return DESTROY_ME;
538 }
539
540 /* add to IKE_SA, and remove from transaction */
541 this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
542 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
543 this->child_sa = NULL;
544 return SUCCESS;
545 }
546
547 /**
548 * Implementation of transaction_t.get_response.
549 */
550 static status_t get_response(private_ike_auth_t *this, message_t *request,
551 message_t **result, transaction_t **next)
552 {
553 host_t *me, *other;
554 identification_t *my_id, *other_id;
555 message_t *response;
556 status_t status;
557 iterator_t *payloads;
558 id_payload_t *idi_request = NULL;
559 id_payload_t *idr_request = NULL;
560 auth_payload_t *auth_request = NULL;
561 cert_payload_t *cert_request = NULL;
562 sa_payload_t *sa_request = NULL;
563 ts_payload_t *tsi_request = NULL;
564 ts_payload_t *tsr_request = NULL;
565 id_payload_t *idr_response;
566
567 /* check if we already have built a response (retransmission) */
568 if (this->message)
569 {
570 *result = this->message;
571 return SUCCESS;
572 }
573
574 me = this->ike_sa->get_my_host(this->ike_sa);
575 other = this->ike_sa->get_other_host(this->ike_sa);
576 this->message_id = request->get_message_id(request);
577
578 /* set up response */
579 response = message_create();
580 response->set_source(response, me->clone(me));
581 response->set_destination(response, other->clone(other));
582 response->set_exchange_type(response, IKE_AUTH);
583 response->set_request(response, FALSE);
584 response->set_message_id(response, this->message_id);
585 response->set_ike_sa_id(response, this->ike_sa->get_id(this->ike_sa));
586 this->message = response;
587 *result = response;
588
589 /* check message type */
590 if (request->get_exchange_type(request) != IKE_AUTH)
591 {
592 this->logger->log(this->logger, ERROR,
593 "IKE_AUTH response of invalid type, deleting IKE_SA");
594 return DESTROY_ME;
595 }
596
597 /* Iterate over all payloads. */
598 payloads = request->get_payload_iterator(request);
599 while (payloads->has_next(payloads))
600 {
601 payload_t *payload;
602 payloads->current(payloads, (void**)&payload);
603 switch (payload->get_type(payload))
604 {
605 case ID_INITIATOR:
606 idi_request = (id_payload_t*)payload;
607 break;
608 case ID_RESPONDER:
609 idr_request = (id_payload_t*)payload;
610 break;
611 case AUTHENTICATION:
612 auth_request = (auth_payload_t*)payload;
613 break;
614 case CERTIFICATE:
615 cert_request = (cert_payload_t*)payload;
616 break;
617 case SECURITY_ASSOCIATION:
618 sa_request = (sa_payload_t*)payload;
619 break;
620 case TRAFFIC_SELECTOR_INITIATOR:
621 tsi_request = (ts_payload_t*)payload;
622 break;
623 case TRAFFIC_SELECTOR_RESPONDER:
624 tsr_request = (ts_payload_t*)payload;
625 break;
626 case NOTIFY:
627 {
628 status = process_notifies(this, (notify_payload_t*)payload);
629 if (status == FAILED)
630 {
631 payloads->destroy(payloads);
632 /* we return SUCCESS, returned FAILED means do next transaction */
633 return SUCCESS;
634 }
635 if (status == DESTROY_ME)
636 {
637 payloads->destroy(payloads);
638 return DESTROY_ME;
639 }
640 break;
641 }
642 default:
643 {
644 this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)",
645 mapping_find(payload_type_m, payload->get_type(payload)),
646 payload->get_type(payload));
647 break;
648 }
649 }
650 }
651 payloads->destroy(payloads);
652
653 /* check if we have all payloads */
654 if (!(idi_request && auth_request && sa_request && tsi_request && tsr_request))
655 {
656 build_notify(INVALID_SYNTAX, response, TRUE);
657 this->logger->log(this->logger, AUDIT,
658 "request message incomplete, deleting IKE_SA");
659 return DESTROY_ME;
660 }
661
662 { /* process ID payload */
663 other_id = idi_request->get_identification(idi_request);
664 if (idr_request)
665 {
666 my_id = idr_request->get_identification(idr_request);
667 }
668 else
669 {
670 my_id = identification_create_from_encoding(ID_ANY, CHUNK_INITIALIZER);
671 }
672 }
673
674 { /* get a policy and process traffic selectors */
675 linked_list_t *my_ts, *other_ts;
676
677 my_ts = tsr_request->get_traffic_selectors(tsr_request);
678 other_ts = tsi_request->get_traffic_selectors(tsi_request);
679
680 this->policy = charon->policies->get_policy(charon->policies,
681 my_id, other_id,
682 my_ts, other_ts,
683 me, other);
684 if (this->policy)
685 {
686 this->tsr = this->policy->select_my_traffic_selectors(this->policy, my_ts, me);
687 this->tsi = this->policy->select_other_traffic_selectors(this->policy, other_ts, other);
688 }
689 destroy_ts_list(my_ts);
690 destroy_ts_list(other_ts);
691
692 /* TODO: We should check somehow if we have a policy, but with other
693 * traffic selectors. Then we would create a IKE_SA without a CHILD_SA. */
694 if (this->policy == NULL)
695 {
696 this->logger->log(this->logger, AUDIT,
697 "no acceptable policy for IDs %s - %s found, deleting IKE_SA",
698 my_id->get_string(my_id), other_id->get_string(other_id));
699 my_id->destroy(my_id);
700 other_id->destroy(other_id);
701 build_notify(AUTHENTICATION_FAILED, response, TRUE);
702 return DESTROY_ME;
703 }
704 my_id->destroy(my_id);
705
706 /* get my id from policy, which must contain a fully qualified valid id */
707 my_id = this->policy->get_my_id(this->policy);
708 this->ike_sa->set_my_id(this->ike_sa, my_id->clone(my_id));
709 this->ike_sa->set_other_id(this->ike_sa, other_id);
710
711 idr_response = id_payload_create_from_identification(FALSE, my_id);
712 response->add_payload(response, (payload_t*)idr_response);
713 }
714
715 if (this->policy->get_auth_method(this->policy) == RSA_DIGITAL_SIGNATURE
716 && this->connection->get_cert_policy(this->connection) != CERT_NEVER_SEND)
717 { /* build certificate payload */
718 x509_t *cert;
719 cert_payload_t *cert_payload;
720
721 cert = charon->credentials->get_certificate(charon->credentials, my_id);
722 if (cert)
723 {
724 cert_payload = cert_payload_create_from_x509(cert);
725 response->add_payload(response, (payload_t *)cert_payload);
726 }
727 else
728 {
729 this->logger->log(this->logger, ERROR,
730 "could not find my certificate, cert payload omitted");
731 }
732 }
733
734 if (cert_request)
735 { /* process certificate payload */
736 import_certificate(this, cert_request);
737 }
738
739 { /* process auth payload */
740 authenticator_t *authenticator;
741 auth_payload_t *auth_response;
742 auth_method_t auth_method;
743 status_t status;
744
745 auth_method = this->policy->get_auth_method(this->policy);
746 authenticator = authenticator_create(this->ike_sa, auth_method);
747 status = authenticator->verify_auth_data(authenticator, auth_request,
748 this->init_request,
749 this->nonce_r,
750 my_id,
751 other_id,
752 TRUE);
753 if (status != SUCCESS)
754 {
755 this->logger->log(this->logger, AUDIT,
756 "authentication failed, deleting IKE_SA");
757 build_notify(AUTHENTICATION_FAILED, response, TRUE);
758 authenticator->destroy(authenticator);
759 return DESTROY_ME;
760 }
761 status = authenticator->compute_auth_data(authenticator, &auth_response,
762 this->init_response,
763 this->nonce_i,
764 my_id,
765 other_id,
766 FALSE);
767 authenticator->destroy(authenticator);
768 if (status != SUCCESS)
769 {
770 this->logger->log(this->logger, AUDIT,
771 "authentication data generation failed, deleting IKE_SA");
772 build_notify(AUTHENTICATION_FAILED, response, TRUE);
773 return DESTROY_ME;
774 }
775 response->add_payload(response, (payload_t*)auth_response);
776 }
777
778 { /* process SA payload */
779 linked_list_t *proposal_list;
780 sa_payload_t *sa_response;
781 ts_payload_t *ts_response;
782 bool use_natt;
783 u_int32_t soft_lifetime, hard_lifetime;
784
785 /* prepare reply */
786 sa_response = sa_payload_create();
787
788 /* get proposals from request, and select one with ours */
789 proposal_list = sa_request->get_proposals(sa_request);
790 this->logger->log(this->logger, CONTROL|LEVEL1, "selecting proposals:");
791 this->proposal = this->policy->select_proposal(this->policy, proposal_list);
792 destroy_proposal_list(proposal_list);
793
794 /* do we have a proposal? */
795 if (this->proposal == NULL)
796 {
797 this->logger->log(this->logger, AUDIT,
798 "CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
799 build_notify(NO_PROPOSAL_CHOSEN, response, FALSE);
800 }
801 /* do we have traffic selectors? */
802 else if (this->tsi->get_count(this->tsi) == 0 || this->tsr->get_count(this->tsr) == 0)
803 {
804 this->logger->log(this->logger, AUDIT,
805 "CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
806 build_notify(TS_UNACCEPTABLE, response, FALSE);
807 }
808 else
809 {
810 /* create child sa */
811 soft_lifetime = this->policy->get_soft_lifetime(this->policy);
812 hard_lifetime = this->policy->get_hard_lifetime(this->policy);
813 use_natt = this->ike_sa->is_natt_enabled(this->ike_sa);
814 this->child_sa = child_sa_create(this->reqid, me, other, my_id, other_id,
815 soft_lifetime, hard_lifetime,
816 this->policy->get_updown(this->policy),
817 this->policy->get_hostaccess(this->policy),
818 use_natt);
819 this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
820 if (install_child_sa(this, FALSE) != SUCCESS)
821 {
822 this->logger->log(this->logger, ERROR,
823 "installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
824 build_notify(NO_PROPOSAL_CHOSEN, response, FALSE);
825 }
826 /* add proposal to sa payload */
827 sa_response->add_proposal(sa_response, this->proposal);
828 }
829 response->add_payload(response, (payload_t*)sa_response);
830
831 /* add ts payload after sa payload */
832 ts_response = ts_payload_create_from_traffic_selectors(TRUE, this->tsi);
833 response->add_payload(response, (payload_t*)ts_response);
834 ts_response = ts_payload_create_from_traffic_selectors(FALSE, this->tsr);
835 response->add_payload(response, (payload_t*)ts_response);
836 }
837 /* set established state */
838 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
839 return SUCCESS;
840 }
841
842
843 /**
844 * Implementation of transaction_t.conclude
845 */
846 static status_t conclude(private_ike_auth_t *this, message_t *response,
847 transaction_t **transaction)
848 {
849 iterator_t *payloads;
850 host_t *me, *other;
851 identification_t *other_id;
852 ts_payload_t *tsi_payload = NULL;
853 ts_payload_t *tsr_payload = NULL;
854 id_payload_t *idr_payload = NULL;
855 cert_payload_t *cert_payload = NULL;
856 auth_payload_t *auth_payload = NULL;
857 sa_payload_t *sa_payload = NULL;
858 status_t status;
859
860 /* check message type */
861 if (response->get_exchange_type(response) != IKE_AUTH)
862 {
863 this->logger->log(this->logger, ERROR,
864 "IKE_AUTH response of invalid type, deleting IKE_SA");
865 return DESTROY_ME;
866 }
867
868 me = this->ike_sa->get_my_host(this->ike_sa);
869 other = this->ike_sa->get_other_host(this->ike_sa);
870
871 /* Iterate over all payloads to collect them */
872 payloads = response->get_payload_iterator(response);
873 while (payloads->has_next(payloads))
874 {
875 payload_t *payload;
876 payloads->current(payloads, (void**)&payload);
877
878 switch (payload->get_type(payload))
879 {
880 case ID_RESPONDER:
881 idr_payload = (id_payload_t*)payload;
882 break;
883 case AUTHENTICATION:
884 auth_payload = (auth_payload_t*)payload;
885 break;
886 case CERTIFICATE:
887 cert_payload = (cert_payload_t*)payload;
888 break;
889 case SECURITY_ASSOCIATION:
890 sa_payload = (sa_payload_t*)payload;
891 break;
892 case TRAFFIC_SELECTOR_INITIATOR:
893 tsi_payload = (ts_payload_t*)payload;
894 break;
895 case TRAFFIC_SELECTOR_RESPONDER:
896 tsr_payload = (ts_payload_t*)payload;
897 break;
898 case NOTIFY:
899 {
900 status = process_notifies(this, (notify_payload_t*)payload);
901 if (status == FAILED)
902 {
903 payloads->destroy(payloads);
904 /* we return SUCCESS, returned FAILED means do next transaction */
905 return SUCCESS;
906 }
907 if (status == DESTROY_ME)
908 {
909 payloads->destroy(payloads);
910 return status;
911 }
912 break;
913 }
914 default:
915 {
916 this->logger->log(this->logger, CONTROL, "ignoring payload %s (%d)",
917 mapping_find(payload_type_m, payload->get_type(payload)),
918 payload->get_type(payload));
919 break;
920 }
921 }
922 }
923 payloads->destroy(payloads);
924
925 if (!(idr_payload && auth_payload && sa_payload && tsi_payload && tsr_payload))
926 {
927 this->logger->log(this->logger, AUDIT, "response message incomplete, deleting IKE_SA");
928 return DESTROY_ME;
929 }
930
931 { /* process idr payload */
932 identification_t *configured_other_id;
933 int wildcards;
934
935 other_id = idr_payload->get_identification(idr_payload);
936 configured_other_id = this->policy->get_other_id(this->policy);
937
938 if (!other_id->matches(other_id, configured_other_id, &wildcards))
939 {
940 other_id->destroy(other_id);
941 this->logger->log(this->logger, AUDIT,
942 "other peer uses unacceptable ID (%s, excepted %s), deleting IKE_SA",
943 other_id->get_string(other_id),
944 configured_other_id->get_string(configured_other_id));
945 return DESTROY_ME;
946 }
947 /* update other ID. It was already set, but may contain wildcards */
948 this->ike_sa->set_other_id(this->ike_sa, other_id);
949 }
950
951 if (cert_payload)
952 { /* process cert payload */
953 import_certificate(this, cert_payload);
954 }
955
956 { /* authenticate peer */
957 authenticator_t *authenticator;
958 auth_method_t auth_method;
959 identification_t *my_id;
960 status_t status;
961
962 auth_method = this->policy->get_auth_method(this->policy);
963 authenticator = authenticator_create(this->ike_sa, auth_method);
964 my_id = this->policy->get_my_id(this->policy);
965
966 status = authenticator->verify_auth_data(authenticator,
967 auth_payload,
968 this->init_response,
969 this->nonce_i,
970 my_id,
971 other_id,
972 FALSE);
973 authenticator->destroy(authenticator);
974 if (status != SUCCESS)
975 {
976 this->logger->log(this->logger, AUDIT, "authentication failed, deleting IKE_SA");
977 return DESTROY_ME;
978 }
979 }
980
981 { /* process traffic selectors for us */
982 linked_list_t *ts_received = tsi_payload->get_traffic_selectors(tsi_payload);
983 this->tsi = this->policy->select_my_traffic_selectors(this->policy, ts_received, me);
984 destroy_ts_list(ts_received);
985 }
986
987 { /* process traffic selectors for other */
988 linked_list_t *ts_received = tsr_payload->get_traffic_selectors(tsr_payload);
989 this->tsr = this->policy->select_other_traffic_selectors(this->policy, ts_received, other);
990 destroy_ts_list(ts_received);
991 }
992
993 { /* process sa payload */
994 linked_list_t *proposal_list;
995
996 proposal_list = sa_payload->get_proposals(sa_payload);
997 /* we have to re-check here if other's selection is valid */
998 this->proposal = this->policy->select_proposal(this->policy, proposal_list);
999 destroy_proposal_list(proposal_list);
1000
1001 /* everything fine to create CHILD? */
1002 if (this->proposal == NULL ||
1003 this->tsi->get_count(this->tsi) == 0 ||
1004 this->tsr->get_count(this->tsr) == 0 ||
1005 !this->build_child)
1006 {
1007 this->logger->log(this->logger, AUDIT,
1008 "CHILD_SA creation failed");
1009 }
1010 else
1011 {
1012 if (install_child_sa(this, TRUE) != SUCCESS)
1013 {
1014 this->logger->log(this->logger, ERROR,
1015 "installing CHILD_SA failed, no CHILD_SA built");
1016 }
1017 }
1018 }
1019 /* set new state */
1020 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1021 return SUCCESS;
1022 }
1023
1024 /**
1025 * implements transaction_t.destroy
1026 */
1027 static void destroy(private_ike_auth_t *this)
1028 {
1029 DESTROY_IF(this->message);
1030 DESTROY_IF(this->proposal);
1031 DESTROY_IF(this->child_sa);
1032 DESTROY_IF(this->policy);
1033 DESTROY_IF(this->connection);
1034 destroy_ts_list(this->tsi);
1035 destroy_ts_list(this->tsr);
1036 chunk_free(&this->nonce_i);
1037 chunk_free(&this->nonce_r);
1038 chunk_free(&this->init_request);
1039 chunk_free(&this->init_response);
1040 free(this);
1041 }
1042
1043 /*
1044 * Described in header.
1045 */
1046 ike_auth_t *ike_auth_create(ike_sa_t *ike_sa)
1047 {
1048 private_ike_auth_t *this = malloc_thing(private_ike_auth_t);
1049
1050 /* transaction interface functions */
1051 this->public.transaction.get_request = (status_t(*)(transaction_t*,message_t**))get_request;
1052 this->public.transaction.get_response = (status_t(*)(transaction_t*,message_t*,message_t**,transaction_t**))get_response;
1053 this->public.transaction.conclude = (status_t(*)(transaction_t*,message_t*,transaction_t**))conclude;
1054 this->public.transaction.get_message_id = (u_int32_t(*)(transaction_t*))get_message_id;
1055 this->public.transaction.requested = (u_int32_t(*)(transaction_t*))requested;
1056 this->public.transaction.destroy = (void(*)(transaction_t*))destroy;
1057
1058 /* public functions */
1059 this->public.set_config = (void(*)(ike_auth_t*,connection_t*,policy_t*))set_config;
1060 this->public.set_reqid = (void(*)(ike_auth_t*,u_int32_t))set_reqid;
1061 this->public.set_nonces = (void(*)(ike_auth_t*,chunk_t,chunk_t))set_nonces;
1062 this->public.set_init_messages = (void(*)(ike_auth_t*,chunk_t,chunk_t))set_init_messages;
1063
1064 /* private data */
1065 this->ike_sa = ike_sa;
1066 this->message_id = 0;
1067 this->message = NULL;
1068 this->requested = 0;
1069 this->nonce_i = CHUNK_INITIALIZER;
1070 this->nonce_r = CHUNK_INITIALIZER;
1071 this->init_request = CHUNK_INITIALIZER;
1072 this->init_response = CHUNK_INITIALIZER;
1073 this->child_sa = NULL;
1074 this->proposal = NULL;
1075 this->tsi = NULL;
1076 this->tsr = NULL;
1077 this->build_child = TRUE;
1078 this->reqid = 0;
1079 this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
1080
1081 return &this->public;
1082 }