added PSK support
[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->connection->get_auth_method(this->connection) == 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->connection->get_auth_method(this->connection);
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 enable_natt);
332 this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
333 if (this->child_sa->alloc(this->child_sa, proposal_list) != SUCCESS)
334 {
335 this->logger->log(this->logger, ERROR,
336 "could not install CHILD_SA, deleting IKE_SA");
337 return DESTROY_ME;
338 }
339 sa_payload = sa_payload_create_from_proposal_list(proposal_list);
340 destroy_proposal_list(proposal_list);
341 request->add_payload(request, (payload_t*)sa_payload);
342 }
343
344 { /* build TSi payload */
345 linked_list_t *ts_list;
346 ts_payload_t *ts_payload;
347
348 ts_list = this->policy->get_my_traffic_selectors(this->policy, me);
349 ts_payload = ts_payload_create_from_traffic_selectors(TRUE, ts_list);
350 destroy_ts_list(ts_list);
351
352 request->add_payload(request, (payload_t*)ts_payload);
353 }
354
355 { /* build TSr payload */
356 linked_list_t *ts_list;
357 ts_payload_t *ts_payload;
358
359 ts_list = this->policy->get_other_traffic_selectors(this->policy, other);
360 ts_payload = ts_payload_create_from_traffic_selectors(FALSE, ts_list);
361 destroy_ts_list(ts_list);
362
363 request->add_payload(request, (payload_t*)ts_payload);
364 }
365
366 this->message_id = this->ike_sa->get_next_message_id(this->ike_sa);
367 request->set_message_id(request, this->message_id);
368 return SUCCESS;
369 }
370
371 /**
372 * Handle all kind of notifies
373 */
374 static status_t process_notifies(private_ike_auth_t *this, notify_payload_t *notify_payload)
375 {
376 notify_type_t notify_type = notify_payload->get_notify_type(notify_payload);
377
378 this->logger->log(this->logger, CONTROL|LEVEL1, "process notify type %s",
379 mapping_find(notify_type_m, notify_type));
380
381 switch (notify_type)
382 {
383 /* these notifies are not critical. no child_sa is built, but IKE stays alive */
384 case SINGLE_PAIR_REQUIRED:
385 {
386 this->logger->log(this->logger, AUDIT,
387 "received a SINGLE_PAIR_REQUIRED notify");
388 this->build_child = FALSE;
389 return SUCCESS;
390 }
391 case TS_UNACCEPTABLE:
392 {
393 this->logger->log(this->logger, CONTROL,
394 "received TS_UNACCEPTABLE notify");
395 this->build_child = FALSE;
396 return SUCCESS;
397 }
398 case NO_PROPOSAL_CHOSEN:
399 {
400 this->logger->log(this->logger, CONTROL,
401 "received NO_PROPOSAL_CHOSEN notify");
402 this->build_child = FALSE;
403 return SUCCESS;
404 }
405 default:
406 {
407 if (notify_type < 16383)
408 {
409 this->logger->log(this->logger, AUDIT,
410 "received %s notify error (%d), deleting IKE_SA",
411 mapping_find(notify_type_m, notify_type),
412 notify_type);
413 return DESTROY_ME;
414 }
415 else
416 {
417 this->logger->log(this->logger, CONTROL,
418 "received %s notify (%d), ignored",
419 mapping_find(notify_type_m, notify_type),
420 notify_type);
421 return SUCCESS;
422 }
423 }
424 }
425 }
426
427 /**
428 * Build a notify message.
429 */
430 static void build_notify(notify_type_t type, message_t *message, bool flush_message)
431 {
432 notify_payload_t *notify;
433
434 if (flush_message)
435 {
436 payload_t *payload;
437 iterator_t *iterator = message->get_payload_iterator(message);
438 while (iterator->iterate(iterator, (void**)&payload))
439 {
440 payload->destroy(payload);
441 iterator->remove(iterator);
442 }
443 iterator->destroy(iterator);
444 }
445
446 notify = notify_payload_create();
447 notify->set_notify_type(notify, type);
448 message->add_payload(message, (payload_t*)notify);
449 }
450
451 /**
452 * Import a certificate from a cert payload
453 */
454 static void import_certificate(private_ike_auth_t *this, cert_payload_t *cert_payload)
455 {
456 bool found;
457 x509_t *cert;
458 cert_encoding_t encoding;
459
460 encoding = cert_payload->get_cert_encoding(cert_payload);
461 if (encoding != CERT_X509_SIGNATURE)
462 {
463 this->logger->log(this->logger, ERROR,
464 "certificate payload %s not supported, ignored",
465 enum_name(&cert_encoding_names, encoding));
466 return;
467 }
468 cert = x509_create_from_chunk(cert_payload->get_data_clone(cert_payload));
469 if (cert)
470 {
471 if (charon->credentials->verify(charon->credentials, cert, &found))
472 {
473 this->logger->log(this->logger, CONTROL|LEVEL1,
474 "received end entity certificate is trusted, added to store");
475 if (!found)
476 {
477 charon->credentials->add_end_certificate(charon->credentials, cert);
478 }
479 else
480 {
481 cert->destroy(cert);
482 }
483 }
484 else
485 {
486 this->logger->log(this->logger, CONTROL,
487 "received end entity certificate is not trusted, discarded");
488 cert->destroy(cert);
489 }
490 }
491 else
492 {
493 this->logger->log(this->logger, CONTROL,
494 "parsing of received certificate failed, discarded");
495 }
496 }
497
498 /**
499 * Install a CHILD_SA for usage
500 */
501 static status_t install_child_sa(private_ike_auth_t *this, bool initiator)
502 {
503 prf_plus_t *prf_plus;
504 chunk_t seed;
505 status_t status;
506
507 seed = chunk_alloc(this->nonce_i.len + this->nonce_r.len);
508 memcpy(seed.ptr, this->nonce_i.ptr, this->nonce_i.len);
509 memcpy(seed.ptr + this->nonce_i.len, this->nonce_r.ptr, this->nonce_r.len);
510 prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
511 chunk_free(&seed);
512
513 if (initiator)
514 {
515 status = this->child_sa->update(this->child_sa, this->proposal, prf_plus);
516 }
517 else
518 {
519 status = this->child_sa->add(this->child_sa, this->proposal, prf_plus);
520 }
521 prf_plus->destroy(prf_plus);
522 if (status != SUCCESS)
523 {
524 return DESTROY_ME;
525 }
526 if (initiator)
527 {
528 status = this->child_sa->add_policies(this->child_sa, this->tsi, this->tsr);
529 }
530 else
531 {
532 status = this->child_sa->add_policies(this->child_sa, this->tsr, this->tsi);
533 }
534 if (status != SUCCESS)
535 {
536 return DESTROY_ME;
537 }
538
539 /* add to IKE_SA, and remove from transaction */
540 this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
541 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
542 this->child_sa = NULL;
543 return SUCCESS;
544 }
545
546 /**
547 * Implementation of transaction_t.get_response.
548 */
549 static status_t get_response(private_ike_auth_t *this, message_t *request,
550 message_t **result, transaction_t **next)
551 {
552 host_t *me, *other;
553 identification_t *my_id, *other_id;
554 message_t *response;
555 status_t status;
556 iterator_t *payloads;
557 id_payload_t *idi_request = NULL;
558 id_payload_t *idr_request = NULL;
559 auth_payload_t *auth_request = NULL;
560 cert_payload_t *cert_request = NULL;
561 sa_payload_t *sa_request = NULL;
562 ts_payload_t *tsi_request = NULL;
563 ts_payload_t *tsr_request = NULL;
564 id_payload_t *idr_response;
565
566 /* check if we already have built a response (retransmission) */
567 if (this->message)
568 {
569 *result = this->message;
570 return SUCCESS;
571 }
572
573 me = this->ike_sa->get_my_host(this->ike_sa);
574 other = this->ike_sa->get_other_host(this->ike_sa);
575 this->message_id = request->get_message_id(request);
576
577 /* set up response */
578 response = message_create();
579 response->set_source(response, me->clone(me));
580 response->set_destination(response, other->clone(other));
581 response->set_exchange_type(response, IKE_AUTH);
582 response->set_request(response, FALSE);
583 response->set_message_id(response, this->message_id);
584 response->set_ike_sa_id(response, this->ike_sa->get_id(this->ike_sa));
585 this->message = response;
586 *result = response;
587
588 /* check message type */
589 if (request->get_exchange_type(request) != IKE_AUTH)
590 {
591 this->logger->log(this->logger, ERROR,
592 "IKE_AUTH response of invalid type, deleting IKE_SA");
593 return DESTROY_ME;
594 }
595
596 /* Iterate over all payloads. */
597 payloads = request->get_payload_iterator(request);
598 while (payloads->has_next(payloads))
599 {
600 payload_t *payload;
601 payloads->current(payloads, (void**)&payload);
602 switch (payload->get_type(payload))
603 {
604 case ID_INITIATOR:
605 idi_request = (id_payload_t*)payload;
606 break;
607 case ID_RESPONDER:
608 idr_request = (id_payload_t*)payload;
609 break;
610 case AUTHENTICATION:
611 auth_request = (auth_payload_t*)payload;
612 break;
613 case CERTIFICATE:
614 cert_request = (cert_payload_t*)payload;
615 break;
616 case SECURITY_ASSOCIATION:
617 sa_request = (sa_payload_t*)payload;
618 break;
619 case TRAFFIC_SELECTOR_INITIATOR:
620 tsi_request = (ts_payload_t*)payload;
621 break;
622 case TRAFFIC_SELECTOR_RESPONDER:
623 tsr_request = (ts_payload_t*)payload;
624 break;
625 case NOTIFY:
626 {
627 status = process_notifies(this, (notify_payload_t*)payload);
628 if (status == FAILED)
629 {
630 payloads->destroy(payloads);
631 /* we return SUCCESS, returned FAILED means do next transaction */
632 return SUCCESS;
633 }
634 if (status == DESTROY_ME)
635 {
636 payloads->destroy(payloads);
637 return DESTROY_ME;
638 }
639 break;
640 }
641 default:
642 {
643 this->logger->log(this->logger, ERROR, "ignoring %s payload (%d)",
644 mapping_find(payload_type_m, payload->get_type(payload)),
645 payload->get_type(payload));
646 break;
647 }
648 }
649 }
650 payloads->destroy(payloads);
651
652 /* check if we have all payloads */
653 if (!(idi_request && auth_request && sa_request && tsi_request && tsr_request))
654 {
655 build_notify(INVALID_SYNTAX, response, TRUE);
656 this->logger->log(this->logger, AUDIT,
657 "request message incomplete, deleting IKE_SA");
658 return DESTROY_ME;
659 }
660
661 { /* process ID payload */
662 other_id = idi_request->get_identification(idi_request);
663 if (idr_request)
664 {
665 my_id = idr_request->get_identification(idr_request);
666 }
667 else
668 {
669 my_id = identification_create_from_encoding(ID_ANY, CHUNK_INITIALIZER);
670 }
671 }
672
673 { /* get a policy and process traffic selectors */
674 linked_list_t *my_ts, *other_ts;
675
676 my_ts = tsr_request->get_traffic_selectors(tsr_request);
677 other_ts = tsi_request->get_traffic_selectors(tsi_request);
678
679 this->policy = charon->policies->get_policy(charon->policies,
680 my_id, other_id,
681 my_ts, other_ts,
682 me, other);
683 if (this->policy)
684 {
685 this->tsr = this->policy->select_my_traffic_selectors(this->policy, my_ts, me);
686 this->tsi = this->policy->select_other_traffic_selectors(this->policy, other_ts, other);
687 }
688 destroy_ts_list(my_ts);
689 destroy_ts_list(other_ts);
690
691 /* TODO: We should check somehow if we have a policy, but with other
692 * traffic selectors. Then we would create a IKE_SA without a CHILD_SA. */
693 if (this->policy == NULL)
694 {
695 this->logger->log(this->logger, AUDIT,
696 "no acceptable policy for IDs %s - %s found, deleting IKE_SA",
697 my_id->get_string(my_id), other_id->get_string(other_id));
698 my_id->destroy(my_id);
699 other_id->destroy(other_id);
700 build_notify(AUTHENTICATION_FAILED, response, TRUE);
701 return DESTROY_ME;
702 }
703 my_id->destroy(my_id);
704
705 /* get my id from policy, which must contain a fully qualified valid id */
706 my_id = this->policy->get_my_id(this->policy);
707 this->ike_sa->set_my_id(this->ike_sa, my_id->clone(my_id));
708 this->ike_sa->set_other_id(this->ike_sa, other_id);
709
710 idr_response = id_payload_create_from_identification(FALSE, my_id);
711 response->add_payload(response, (payload_t*)idr_response);
712 }
713
714 if (this->connection->get_auth_method(this->connection) == RSA_DIGITAL_SIGNATURE
715 && this->connection->get_cert_policy(this->connection) != CERT_NEVER_SEND)
716 { /* build certificate payload */
717 x509_t *cert;
718 cert_payload_t *cert_payload;
719
720 cert = charon->credentials->get_certificate(charon->credentials, my_id);
721 if (cert)
722 {
723 cert_payload = cert_payload_create_from_x509(cert);
724 response->add_payload(response, (payload_t *)cert_payload);
725 }
726 else
727 {
728 this->logger->log(this->logger, ERROR,
729 "could not find my certificate, cert payload omitted");
730 }
731 }
732
733 if (cert_request)
734 { /* process certificate payload */
735 import_certificate(this, cert_request);
736 }
737
738 { /* process auth payload */
739 authenticator_t *authenticator;
740 auth_payload_t *auth_response;
741 auth_method_t auth_method;
742 status_t status;
743
744 auth_method = this->connection->get_auth_method(this->connection);
745 authenticator = authenticator_create(this->ike_sa, auth_method);
746 status = authenticator->verify_auth_data(authenticator, auth_request,
747 this->init_request,
748 this->nonce_r,
749 my_id,
750 other_id,
751 TRUE);
752 if (status != SUCCESS)
753 {
754 this->logger->log(this->logger, AUDIT,
755 "authentication failed, deleting IKE_SA");
756 build_notify(AUTHENTICATION_FAILED, response, TRUE);
757 authenticator->destroy(authenticator);
758 return DESTROY_ME;
759 }
760 status = authenticator->compute_auth_data(authenticator, &auth_response,
761 this->init_response,
762 this->nonce_i,
763 my_id,
764 other_id,
765 FALSE);
766 authenticator->destroy(authenticator);
767 if (status != SUCCESS)
768 {
769 this->logger->log(this->logger, AUDIT,
770 "authentication data generation failed, deleting IKE_SA");
771 build_notify(AUTHENTICATION_FAILED, response, TRUE);
772 return DESTROY_ME;
773 }
774 response->add_payload(response, (payload_t*)auth_response);
775 }
776
777 { /* process SA payload */
778 linked_list_t *proposal_list;
779 sa_payload_t *sa_response;
780 ts_payload_t *ts_response;
781 bool use_natt;
782 u_int32_t soft_lifetime, hard_lifetime;
783
784 /* prepare reply */
785 sa_response = sa_payload_create();
786
787 /* get proposals from request, and select one with ours */
788 proposal_list = sa_request->get_proposals(sa_request);
789 this->logger->log(this->logger, CONTROL|LEVEL1, "selecting proposals:");
790 this->proposal = this->policy->select_proposal(this->policy, proposal_list);
791 destroy_proposal_list(proposal_list);
792
793 /* do we have a proposal? */
794 if (this->proposal == NULL)
795 {
796 this->logger->log(this->logger, AUDIT,
797 "CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
798 build_notify(NO_PROPOSAL_CHOSEN, response, FALSE);
799 }
800 /* do we have traffic selectors? */
801 else if (this->tsi->get_count(this->tsi) == 0 || this->tsr->get_count(this->tsr) == 0)
802 {
803 this->logger->log(this->logger, AUDIT,
804 "CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
805 build_notify(TS_UNACCEPTABLE, response, FALSE);
806 }
807 else
808 {
809 /* create child sa */
810 soft_lifetime = this->policy->get_soft_lifetime(this->policy);
811 hard_lifetime = this->policy->get_hard_lifetime(this->policy);
812 use_natt = this->ike_sa->is_natt_enabled(this->ike_sa);
813 this->child_sa = child_sa_create(this->reqid, me, other, my_id, other_id,
814 soft_lifetime, hard_lifetime,
815 this->policy->get_updown(this->policy),
816 use_natt);
817 this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
818 if (install_child_sa(this, FALSE) != SUCCESS)
819 {
820 this->logger->log(this->logger, ERROR,
821 "installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
822 build_notify(NO_PROPOSAL_CHOSEN, response, FALSE);
823 }
824 /* add proposal to sa payload */
825 sa_response->add_proposal(sa_response, this->proposal);
826 }
827 response->add_payload(response, (payload_t*)sa_response);
828
829 /* add ts payload after sa payload */
830 ts_response = ts_payload_create_from_traffic_selectors(TRUE, this->tsi);
831 response->add_payload(response, (payload_t*)ts_response);
832 ts_response = ts_payload_create_from_traffic_selectors(FALSE, this->tsr);
833 response->add_payload(response, (payload_t*)ts_response);
834 }
835 /* set established state */
836 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
837 return SUCCESS;
838 }
839
840
841 /**
842 * Implementation of transaction_t.conclude
843 */
844 static status_t conclude(private_ike_auth_t *this, message_t *response,
845 transaction_t **transaction)
846 {
847 iterator_t *payloads;
848 host_t *me, *other;
849 identification_t *other_id;
850 ts_payload_t *tsi_payload = NULL;
851 ts_payload_t *tsr_payload = NULL;
852 id_payload_t *idr_payload = NULL;
853 cert_payload_t *cert_payload = NULL;
854 auth_payload_t *auth_payload = NULL;
855 sa_payload_t *sa_payload = NULL;
856 status_t status;
857
858 /* check message type */
859 if (response->get_exchange_type(response) != IKE_AUTH)
860 {
861 this->logger->log(this->logger, ERROR,
862 "IKE_AUTH response of invalid type, deleting IKE_SA");
863 return DESTROY_ME;
864 }
865
866 me = this->ike_sa->get_my_host(this->ike_sa);
867 other = this->ike_sa->get_other_host(this->ike_sa);
868
869 /* Iterate over all payloads to collect them */
870 payloads = response->get_payload_iterator(response);
871 while (payloads->has_next(payloads))
872 {
873 payload_t *payload;
874 payloads->current(payloads, (void**)&payload);
875
876 switch (payload->get_type(payload))
877 {
878 case ID_RESPONDER:
879 idr_payload = (id_payload_t*)payload;
880 break;
881 case AUTHENTICATION:
882 auth_payload = (auth_payload_t*)payload;
883 break;
884 case CERTIFICATE:
885 cert_payload = (cert_payload_t*)payload;
886 break;
887 case SECURITY_ASSOCIATION:
888 sa_payload = (sa_payload_t*)payload;
889 break;
890 case TRAFFIC_SELECTOR_INITIATOR:
891 tsi_payload = (ts_payload_t*)payload;
892 break;
893 case TRAFFIC_SELECTOR_RESPONDER:
894 tsr_payload = (ts_payload_t*)payload;
895 break;
896 case NOTIFY:
897 {
898 status = process_notifies(this, (notify_payload_t*)payload);
899 if (status == FAILED)
900 {
901 payloads->destroy(payloads);
902 /* we return SUCCESS, returned FAILED means do next transaction */
903 return SUCCESS;
904 }
905 if (status == DESTROY_ME)
906 {
907 payloads->destroy(payloads);
908 return status;
909 }
910 break;
911 }
912 default:
913 {
914 this->logger->log(this->logger, CONTROL, "ignoring payload %s (%d)",
915 mapping_find(payload_type_m, payload->get_type(payload)),
916 payload->get_type(payload));
917 break;
918 }
919 }
920 }
921 payloads->destroy(payloads);
922
923 if (!(idr_payload && auth_payload && sa_payload && tsi_payload && tsr_payload))
924 {
925 this->logger->log(this->logger, AUDIT, "response message incomplete, deleting IKE_SA");
926 return DESTROY_ME;
927 }
928
929 { /* process idr payload */
930 identification_t *configured_other_id;
931 int wildcards;
932
933 other_id = idr_payload->get_identification(idr_payload);
934 configured_other_id = this->policy->get_other_id(this->policy);
935
936 if (!other_id->matches(other_id, configured_other_id, &wildcards))
937 {
938 other_id->destroy(other_id);
939 this->logger->log(this->logger, AUDIT,
940 "other peer uses unacceptable ID (%s, excepted %s), deleting IKE_SA",
941 other_id->get_string(other_id),
942 configured_other_id->get_string(configured_other_id));
943 return DESTROY_ME;
944 }
945 /* update other ID. It was already set, but may contain wildcards */
946 this->ike_sa->set_other_id(this->ike_sa, other_id);
947 }
948
949 if (cert_payload)
950 { /* process cert payload */
951 import_certificate(this, cert_payload);
952 }
953
954 { /* authenticate peer */
955 authenticator_t *authenticator;
956 auth_method_t auth_method;
957 identification_t *my_id;
958 status_t status;
959
960 auth_method = this->connection->get_auth_method(this->connection);
961 authenticator = authenticator_create(this->ike_sa, auth_method);
962 my_id = this->policy->get_my_id(this->policy);
963
964 status = authenticator->verify_auth_data(authenticator,
965 auth_payload,
966 this->init_response,
967 this->nonce_i,
968 my_id,
969 other_id,
970 FALSE);
971 authenticator->destroy(authenticator);
972 if (status != SUCCESS)
973 {
974 this->logger->log(this->logger, AUDIT, "authentication failed, deleting IKE_SA");
975 return DESTROY_ME;
976 }
977 }
978
979 { /* process traffic selectors for us */
980 linked_list_t *ts_received = tsi_payload->get_traffic_selectors(tsi_payload);
981 this->tsi = this->policy->select_my_traffic_selectors(this->policy, ts_received, me);
982 destroy_ts_list(ts_received);
983 }
984
985 { /* process traffic selectors for other */
986 linked_list_t *ts_received = tsr_payload->get_traffic_selectors(tsr_payload);
987 this->tsr = this->policy->select_other_traffic_selectors(this->policy, ts_received, other);
988 destroy_ts_list(ts_received);
989 }
990
991 { /* process sa payload */
992 linked_list_t *proposal_list;
993
994 proposal_list = sa_payload->get_proposals(sa_payload);
995 /* we have to re-check here if other's selection is valid */
996 this->proposal = this->policy->select_proposal(this->policy, proposal_list);
997 destroy_proposal_list(proposal_list);
998
999 /* everything fine to create CHILD? */
1000 if (this->proposal == NULL ||
1001 this->tsi->get_count(this->tsi) == 0 ||
1002 this->tsr->get_count(this->tsr) == 0 ||
1003 !this->build_child)
1004 {
1005 this->logger->log(this->logger, AUDIT,
1006 "CHILD_SA creation failed");
1007 }
1008 else
1009 {
1010 if (install_child_sa(this, TRUE) != SUCCESS)
1011 {
1012 this->logger->log(this->logger, ERROR,
1013 "installing CHILD_SA failed, no CHILD_SA built");
1014 }
1015 }
1016 }
1017 /* set new state */
1018 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1019 return SUCCESS;
1020 }
1021
1022 /**
1023 * implements transaction_t.destroy
1024 */
1025 static void destroy(private_ike_auth_t *this)
1026 {
1027 DESTROY_IF(this->message);
1028 DESTROY_IF(this->proposal);
1029 DESTROY_IF(this->child_sa);
1030 DESTROY_IF(this->policy);
1031 DESTROY_IF(this->connection);
1032 destroy_ts_list(this->tsi);
1033 destroy_ts_list(this->tsr);
1034 chunk_free(&this->nonce_i);
1035 chunk_free(&this->nonce_r);
1036 chunk_free(&this->init_request);
1037 chunk_free(&this->init_response);
1038 free(this);
1039 }
1040
1041 /*
1042 * Described in header.
1043 */
1044 ike_auth_t *ike_auth_create(ike_sa_t *ike_sa)
1045 {
1046 private_ike_auth_t *this = malloc_thing(private_ike_auth_t);
1047
1048 /* transaction interface functions */
1049 this->public.transaction.get_request = (status_t(*)(transaction_t*,message_t**))get_request;
1050 this->public.transaction.get_response = (status_t(*)(transaction_t*,message_t*,message_t**,transaction_t**))get_response;
1051 this->public.transaction.conclude = (status_t(*)(transaction_t*,message_t*,transaction_t**))conclude;
1052 this->public.transaction.get_message_id = (u_int32_t(*)(transaction_t*))get_message_id;
1053 this->public.transaction.requested = (u_int32_t(*)(transaction_t*))requested;
1054 this->public.transaction.destroy = (void(*)(transaction_t*))destroy;
1055
1056 /* public functions */
1057 this->public.set_config = (void(*)(ike_auth_t*,connection_t*,policy_t*))set_config;
1058 this->public.set_reqid = (void(*)(ike_auth_t*,u_int32_t))set_reqid;
1059 this->public.set_nonces = (void(*)(ike_auth_t*,chunk_t,chunk_t))set_nonces;
1060 this->public.set_init_messages = (void(*)(ike_auth_t*,chunk_t,chunk_t))set_init_messages;
1061
1062 /* private data */
1063 this->ike_sa = ike_sa;
1064 this->message_id = 0;
1065 this->message = NULL;
1066 this->requested = 0;
1067 this->nonce_i = CHUNK_INITIALIZER;
1068 this->nonce_r = CHUNK_INITIALIZER;
1069 this->init_request = CHUNK_INITIALIZER;
1070 this->init_response = CHUNK_INITIALIZER;
1071 this->child_sa = NULL;
1072 this->proposal = NULL;
1073 this->tsi = NULL;
1074 this->tsr = NULL;
1075 this->build_child = TRUE;
1076 this->reqid = 0;
1077 this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
1078
1079 return &this->public;
1080 }