- installing of child sa works
[strongswan.git] / Source / charon / sa / states / ike_auth_requested.c
1 /**
2 * @file ike_auth_requested.c
3 *
4 * @brief Implementation of ike_auth_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_auth_requested.h"
24
25 #include <daemon.h>
26 #include <utils/allocator.h>
27 #include <encoding/payloads/ts_payload.h>
28 #include <encoding/payloads/sa_payload.h>
29 #include <encoding/payloads/id_payload.h>
30 #include <encoding/payloads/auth_payload.h>
31 #include <encoding/payloads/notify_payload.h>
32 #include <transforms/signers/signer.h>
33 #include <transforms/crypters/crypter.h>
34 #include <sa/states/ike_sa_established.h>
35 #include <sa/authenticator.h>
36 #include <sa/child_sa.h>
37
38 typedef struct private_ike_auth_requested_t private_ike_auth_requested_t;
39
40 /**
41 * Private data of a ike_auth_requested_t object.
42 *
43 */
44 struct private_ike_auth_requested_t {
45 /**
46 * Public interface of ike_auth_requested_t.
47 */
48 ike_auth_requested_t public;
49
50 /**
51 * Assigned IKE_SA.
52 */
53 protected_ike_sa_t *ike_sa;
54
55 /**
56 * SA config, just a copy of the one stored in the ike_sa.
57 */
58 sa_config_t *sa_config;
59
60 /**
61 * Received nonce from responder.
62 */
63 chunk_t received_nonce;
64
65 /**
66 * Sent nonce in IKE_SA_INIT request.
67 */
68 chunk_t sent_nonce;
69
70 /**
71 * IKE_SA_INIT-Request in binary form.
72 */
73 chunk_t ike_sa_init_reply_data;
74
75 /**
76 * Child sa created in ike_sa_init_requested
77 */
78 child_sa_t *child_sa;
79
80 /**
81 * Assigned Logger.
82 *
83 * Is logger of ike_sa!
84 */
85 logger_t *logger;
86
87 /**
88 * Process the IDr payload (check if other id is valid)
89 *
90 * @param this calling object
91 * @param idr_payload ID payload of responder
92 * @return
93 * - SUCCESS
94 * - DELETE_ME
95 */
96 status_t (*process_idr_payload) (private_ike_auth_requested_t *this, id_payload_t *idr_payload);
97
98 /**
99 * Process the SA payload (check if selected proposals are valid, setup child sa)
100 *
101 * @param this calling object
102 * @param sa_payload SA payload of responder
103 *
104 * - SUCCESS
105 * - DELETE_ME
106 */
107 status_t (*process_sa_payload) (private_ike_auth_requested_t *this, sa_payload_t *sa_payload);
108
109 /**
110 * Process the AUTH payload (check authenticity of message)
111 *
112 * @param this calling object
113 * @param auth_payload AUTH payload of responder
114 * @param other_id_payload ID payload of responder
115 *
116 * - SUCCESS
117 * - DELETE_ME
118 */
119 status_t (*process_auth_payload) (private_ike_auth_requested_t *this, auth_payload_t *auth_payload, id_payload_t *other_id_payload);
120
121 /**
122 * Process the TS payload (check if selected traffic selectors are valid)
123 *
124 * @param this calling object
125 * @param ts_initiator TRUE if TS payload is TSi, FALSE for TSr
126 * @param ts_payload TS payload of responder
127 *
128 * - SUCCESS
129 * - DELETE_ME
130 */
131 status_t (*process_ts_payload) (private_ike_auth_requested_t *this, bool ts_initiator, ts_payload_t *ts_payload);
132
133 /**
134 * Process a notify payload
135 *
136 * @param this calling object
137 * @param notify_payload notify payload
138 *
139 * - SUCCESS
140 * - FAILED
141 * - DELETE_ME
142 */
143 status_t (*process_notify_payload) (private_ike_auth_requested_t *this, notify_payload_t *notify_payload);
144
145 /**
146 * Destroy function called internally of this class after state change to
147 * state IKE_SA_ESTABLISHED succeeded.
148 *
149 * This destroy function does not destroy objects which were passed to the new state.
150 *
151 * @param this calling object
152 */
153 void (*destroy_after_state_change) (private_ike_auth_requested_t *this);
154 };
155
156
157 /**
158 * Implements state_t.process_message
159 */
160 static status_t process_message(private_ike_auth_requested_t *this, message_t *ike_auth_reply)
161 {
162 ts_payload_t *tsi_payload = NULL, *tsr_payload = NULL;
163 id_payload_t *idr_payload = NULL;
164 auth_payload_t *auth_payload = NULL;
165 sa_payload_t *sa_payload = NULL;
166 iterator_t *payloads = NULL;
167 crypter_t *crypter = NULL;
168 signer_t *signer = NULL;
169 status_t status;
170 host_t *my_host, *other_host;
171
172 if (ike_auth_reply->get_exchange_type(ike_auth_reply) != IKE_AUTH)
173 {
174 this->logger->log(this->logger, ERROR | LEVEL1, "Message of type %s not supported in state ike_auth_requested",
175 mapping_find(exchange_type_m,ike_auth_reply->get_exchange_type(ike_auth_reply)));
176 return FAILED;
177 }
178
179 if (ike_auth_reply->get_request(ike_auth_reply))
180 {
181 this->logger->log(this->logger, ERROR | LEVEL1, "IKE_AUTH requests not allowed state ike_sa_init_responded");
182 return FAILED;
183 }
184
185 /* get signer for verification and crypter for decryption */
186 signer = this->ike_sa->get_signer_responder(this->ike_sa);
187 crypter = this->ike_sa->get_crypter_responder(this->ike_sa);
188
189 /* parse incoming message */
190 status = ike_auth_reply->parse_body(ike_auth_reply, crypter, signer);
191 if (status != SUCCESS)
192 {
193 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply decryption failed. Ignoring message");
194 return status;
195 }
196
197 this->sa_config = this->ike_sa->get_sa_config(this->ike_sa);
198
199 /* we collect all payloads, which are processed later. Notify's are processed
200 * in place, since we don't know how may are there.
201 */
202 payloads = ike_auth_reply->get_payload_iterator(ike_auth_reply);
203 while (payloads->has_next(payloads))
204 {
205 payload_t *payload;
206 payloads->current(payloads, (void**)&payload);
207
208 switch (payload->get_type(payload))
209 {
210 case AUTHENTICATION:
211 {
212 auth_payload = (auth_payload_t*)payload;
213 break;
214 }
215 case ID_RESPONDER:
216 {
217 idr_payload = (id_payload_t*)payload;
218 break;
219 }
220 case SECURITY_ASSOCIATION:
221 {
222 sa_payload = (sa_payload_t*)payload;
223 break;
224 }
225 case TRAFFIC_SELECTOR_INITIATOR:
226 {
227 tsi_payload = (ts_payload_t*)payload;
228 break;
229 }
230 case TRAFFIC_SELECTOR_RESPONDER:
231 {
232 tsr_payload = (ts_payload_t*)payload;
233 break;
234 }
235 case NOTIFY:
236 {
237 notify_payload_t *notify_payload = (notify_payload_t *) payload;
238 /* handle the notify directly, abort if no further processing required */
239 status = this->process_notify_payload(this, notify_payload);
240 if (status != SUCCESS)
241 {
242 payloads->destroy(payloads);
243 return status;
244 }
245 }
246 case CERTIFICATE:
247 {
248 /* TODO handle cert payloads */
249 }
250 default:
251 {
252 this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring Payload %s (%d)",
253 mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
254 break;
255 }
256 }
257 }
258 /* iterator can be destroyed */
259 payloads->destroy(payloads);
260
261 /* check if we have all payloads */
262 if (!(idr_payload && sa_payload && auth_payload && tsi_payload && tsr_payload))
263 {
264 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply did not contain all required payloads. Deleting IKE_SA");
265 return DELETE_ME;
266 }
267
268 /* process all payloads */
269 status = this->process_idr_payload(this, idr_payload);
270 if (status != SUCCESS)
271 {
272 return status;
273 }
274 status = this->process_sa_payload(this, sa_payload);
275 if (status != SUCCESS)
276 {
277 return status;
278 }
279 status = this->process_auth_payload(this, auth_payload,idr_payload);
280 if (status != SUCCESS)
281 {
282 return status;
283 }
284 status = this->process_ts_payload(this, TRUE, tsi_payload);
285 if (status != SUCCESS)
286 {
287 return status;
288 }
289 status = this->process_ts_payload(this, FALSE, tsr_payload);
290 if (status != SUCCESS)
291 {
292 return status;
293 }
294
295 this->ike_sa->set_last_replied_message_id(this->ike_sa,ike_auth_reply->get_message_id(ike_auth_reply));
296 /* create new state */
297
298 my_host = this->ike_sa->get_my_host(this->ike_sa);
299 other_host = this->ike_sa->get_other_host(this->ike_sa);
300 this->logger->log(this->logger, AUDIT, "IKE_SA established between %s - %s, authenticated peer with %s",
301 my_host->get_address(my_host), other_host->get_address(other_host),
302 mapping_find(auth_method_m, auth_payload->get_auth_method(auth_payload)));
303
304 this->ike_sa->create_delete_established_ike_sa_job(this->ike_sa,this->sa_config->get_ike_sa_lifetime(this->sa_config));
305 this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa));
306 this->destroy_after_state_change(this);
307 return SUCCESS;
308 }
309
310 /**
311 * Implements private_ike_auth_requested_t.process_idr_payload
312 */
313 static status_t process_idr_payload(private_ike_auth_requested_t *this, id_payload_t *idr_payload)
314 {
315 identification_t *other_id, *configured_other_id;
316
317 other_id = idr_payload->get_identification(idr_payload);
318
319 configured_other_id = this->sa_config->get_other_id(this->sa_config);
320 if (configured_other_id)
321 {
322 this->logger->log(this->logger, CONTROL|LEVEL1, "configured ID: %s, ID of responder: %s",
323 configured_other_id->get_string(configured_other_id),
324 other_id->get_string(other_id));
325
326 if (!other_id->equals(other_id, configured_other_id))
327 {
328 other_id->destroy(other_id);
329 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained a not requested ID. Deleting IKE_SA");
330 return DELETE_ME;
331 }
332 }
333
334 other_id->destroy(other_id);
335 /* TODO do we have to store other_id somewhere ? */
336 return SUCCESS;
337 }
338
339 /**
340 * Implements private_ike_auth_requested_t.process_sa_payload
341 */
342 static status_t process_sa_payload(private_ike_auth_requested_t *this, sa_payload_t *sa_payload)
343 {
344 proposal_t *proposal, *proposal_tmp;
345 linked_list_t *proposal_list;
346 chunk_t seed;
347 prf_plus_t *prf_plus;
348
349 /* get his selected proposal */
350 proposal_list = sa_payload->get_proposals(sa_payload);
351 /* check count of proposals */
352 if (proposal_list->get_count(proposal_list) == 0)
353 {
354 /* no proposal? we accept this, but no child sa is built */
355 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply's SA_PAYLOAD didn't contain any proposals. No CHILD_SA created",
356 proposal_list->get_count(proposal_list));
357 proposal_list->destroy(proposal_list);
358 return SUCCESS;
359 }
360 if (proposal_list->get_count(proposal_list) > 1)
361 {
362 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply's SA_PAYLOAD contained %d proposal. Deleting IKE_SA",
363 proposal_list->get_count(proposal_list));
364 while (proposal_list->remove_last(proposal_list, (void**)&proposal) == SUCCESS)
365 {
366 proposal->destroy(proposal);
367 }
368 proposal_list->destroy(proposal_list);
369 return DELETE_ME;
370 }
371
372 /* we have to re-check here if other's selection is valid */
373 proposal = this->sa_config->select_proposal(this->sa_config, proposal_list);
374 /* list not needed anymore */
375 while (proposal_list->remove_last(proposal_list, (void**)&proposal_tmp) == SUCCESS)
376 {
377 proposal_tmp->destroy(proposal_tmp);
378 }
379 proposal_list->destroy(proposal_list);
380 /* got a match? */
381 if (proposal == NULL)
382 {
383 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained a not offered proposal. Deleting IKE_SA");
384 return DELETE_ME;
385 }
386
387 /* install child SAs for AH and esp */
388 seed = allocator_alloc_as_chunk(this->sent_nonce.len + this->received_nonce.len);
389 memcpy(seed.ptr, this->sent_nonce.ptr, this->sent_nonce.len);
390 memcpy(seed.ptr + this->sent_nonce.len, this->received_nonce.ptr, this->received_nonce.len);
391 prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
392 allocator_free_chunk(&seed);
393
394 if (this->child_sa)
395 {
396 if (this->child_sa->update(this->child_sa, proposal, prf_plus) != SUCCESS)
397 {
398 this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA");
399 prf_plus->destroy(prf_plus);
400 proposal->destroy(proposal);
401 return DELETE_ME;
402 }
403 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
404 }
405
406 prf_plus->destroy(prf_plus);
407 proposal->destroy(proposal);
408
409 return SUCCESS;
410 }
411
412 /**
413 * Implements private_ike_auth_requested_t.process_auth_payload
414 */
415 static status_t process_auth_payload(private_ike_auth_requested_t *this, auth_payload_t *auth_payload, id_payload_t *other_id_payload)
416 {
417 authenticator_t *authenticator;
418 status_t status;
419
420 authenticator = authenticator_create(this->ike_sa);
421 status = authenticator->verify_auth_data(authenticator,auth_payload,this->ike_sa_init_reply_data,this->sent_nonce,other_id_payload,FALSE);
422 authenticator->destroy(authenticator);
423 if (status != SUCCESS)
424 {
425 this->logger->log(this->logger, AUDIT, "Verification of IKE_AUTH reply failed. Deleting IKE_SA");
426 return DELETE_ME;
427 }
428
429 this->logger->log(this->logger, CONTROL|LEVEL1, "AUTH data verified successfully");
430 return SUCCESS;
431 }
432
433 /**
434 * Implements private_ike_auth_requested_t.process_ts_payload
435 */
436 static status_t process_ts_payload(private_ike_auth_requested_t *this, bool ts_initiator, ts_payload_t *ts_payload)
437 {
438 traffic_selector_t **ts_received, **ts_selected;
439 size_t ts_received_count, ts_selected_count;
440 status_t status = SUCCESS;
441
442 /* get ts form payload */
443 ts_received_count = ts_payload->get_traffic_selectors(ts_payload, &ts_received);
444 /* select ts depending on payload type */
445 if (ts_initiator)
446 {
447 ts_selected_count = this->sa_config->select_traffic_selectors_initiator(this->sa_config, ts_received, ts_received_count, &ts_selected);
448 }
449 else
450 {
451 ts_selected_count = this->sa_config->select_traffic_selectors_responder(this->sa_config, ts_received, ts_received_count, &ts_selected);
452 }
453 /* check if the responder selected valid proposals */
454 if (ts_selected_count != ts_received_count)
455 {
456 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained not offered traffic selectors.");
457 }
458
459 /* cleanup */
460 while(ts_received_count--)
461 {
462 traffic_selector_t *ts = *ts_received + ts_received_count;
463 ts->destroy(ts);
464 }
465 allocator_free(ts_received);
466 while(ts_selected_count--)
467 {
468 traffic_selector_t *ts = *ts_selected + ts_selected_count;
469 ts->destroy(ts);
470 }
471 allocator_free(ts_selected);
472 return status;
473 }
474
475 /**
476 * Implements private_ike_auth_requested_t.process_notify_payload
477 */
478 static status_t process_notify_payload(private_ike_auth_requested_t *this, notify_payload_t *notify_payload)
479 {
480 notify_message_type_t notify_message_type = notify_payload->get_notify_message_type(notify_payload);
481
482 this->logger->log(this->logger, CONTROL|LEVEL1, "Process notify type %s for protocol %s",
483 mapping_find(notify_message_type_m, notify_message_type),
484 mapping_find(protocol_id_m, notify_payload->get_protocol_id(notify_payload)));
485
486 if (notify_payload->get_protocol_id(notify_payload) != IKE)
487 {
488 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained a notify for an invalid protocol. Deleting IKE_SA");
489 return DELETE_ME;
490 }
491
492 switch (notify_message_type)
493 {
494 case INVALID_SYNTAX:
495 {
496 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained an INVALID_SYNTAX notify. Deleting IKE_SA");
497 return DELETE_ME;
498
499 }
500 case AUTHENTICATION_FAILED:
501 {
502 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained an AUTHENTICATION_FAILED notify. Deleting IKE_SA");
503 return DELETE_ME;
504
505 }
506 case SINGLE_PAIR_REQUIRED:
507 {
508 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained a SINGLE_PAIR_REQUIRED notify. Deleting IKE_SA");
509 return DELETE_ME;
510 }
511 default:
512 {
513 /*
514 * - In case of unknown error: IKE_SA gets destroyed.
515 * - In case of unknown status: logging
516 */
517
518 if (notify_message_type < 16383)
519 {
520 this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained an unknown notify error (%d). Deleting IKE_SA",
521 notify_message_type);
522 return DELETE_ME;
523
524 }
525 else
526 {
527 this->logger->log(this->logger, CONTROL, "IKE_AUTH reply contained an unknown notify (%d), ignored.",
528 notify_message_type);
529 return SUCCESS;
530 }
531 }
532 }
533 }
534
535 /**
536 * Implements state_t.get_state
537 */
538 static ike_sa_state_t get_state(private_ike_auth_requested_t *this)
539 {
540 return IKE_AUTH_REQUESTED;
541 }
542
543 /**
544 * Implements state_t.get_state
545 */
546 static void destroy(private_ike_auth_requested_t *this)
547 {
548 allocator_free_chunk(&(this->received_nonce));
549 allocator_free_chunk(&(this->sent_nonce));
550 allocator_free_chunk(&(this->ike_sa_init_reply_data));
551 if (this->child_sa)
552 {
553 this->child_sa->destroy(this->child_sa);
554 }
555 allocator_free(this);
556 }
557 /**
558 * Implements protected_ike_sa_t.destroy_after_state_change
559 */
560 static void destroy_after_state_change(private_ike_auth_requested_t *this)
561 {
562 allocator_free_chunk(&(this->received_nonce));
563 allocator_free_chunk(&(this->sent_nonce));
564 allocator_free_chunk(&(this->ike_sa_init_reply_data));
565 allocator_free(this);
566 }
567
568 /*
569 * Described in header.
570 */
571 ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,chunk_t sent_nonce,chunk_t received_nonce,chunk_t ike_sa_init_reply_data, child_sa_t *child_sa)
572 {
573 private_ike_auth_requested_t *this = allocator_alloc_thing(private_ike_auth_requested_t);
574
575 /* interface functions */
576 this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *)) process_message;
577 this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state;
578 this->public.state_interface.destroy = (void (*) (state_t *)) destroy;
579
580 /* private functions */
581 this->process_idr_payload = process_idr_payload;
582 this->process_sa_payload = process_sa_payload;
583 this->process_auth_payload = process_auth_payload;
584 this->process_ts_payload = process_ts_payload;
585 this->process_notify_payload = process_notify_payload;
586 this->destroy_after_state_change = destroy_after_state_change;
587
588 /* private data */
589 this->ike_sa = ike_sa;
590 this->received_nonce = received_nonce;
591 this->sent_nonce = sent_nonce;
592 this->ike_sa_init_reply_data = ike_sa_init_reply_data;
593 this->logger = this->ike_sa->get_logger(this->ike_sa);
594 this->child_sa = child_sa;
595
596 return &(this->public);
597 }