fixed SPI when rekeying and deleting CHILD_SAs
[strongswan.git] / src / charon / sa / states / ike_sa_established.c
1 /**
2 * @file ike_sa_established.c
3 *
4 * @brief Implementation of ike_sa_established_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 <string.h>
24
25 #include "ike_sa_established.h"
26
27 #include <daemon.h>
28 #include <encoding/payloads/delete_payload.h>
29 #include <encoding/payloads/sa_payload.h>
30 #include <encoding/payloads/ts_payload.h>
31 #include <encoding/payloads/nonce_payload.h>
32 #include <sa/child_sa.h>
33 #include <sa/states/delete_ike_sa_requested.h>
34
35
36 typedef struct private_ike_sa_established_t private_ike_sa_established_t;
37
38 /**
39 * Private data of a ike_sa_established_t object.
40 */
41 struct private_ike_sa_established_t {
42 /**
43 * methods of the state_t interface
44 */
45 ike_sa_established_t public;
46
47 /**
48 * Assigned IKE_SA.
49 */
50 protected_ike_sa_t *ike_sa;
51
52 /**
53 * Nonce for a new child SA, chosen by initiator
54 */
55 chunk_t nonce_i;
56
57 /**
58 * Nonce for a new child SA, chosen by responder
59 */
60 chunk_t nonce_r;
61
62 /**
63 * Traffic selectors for a new child SA, responder side
64 */
65 linked_list_t *my_ts;
66
67 /**
68 * Traffic selectors for a new child SA, initiator side
69 */
70 linked_list_t *other_ts;
71
72 /**
73 * Newly set up child sa
74 */
75 child_sa_t *child_sa;
76
77 /**
78 * Old child sa, if we are rekeying
79 */
80 child_sa_t *old_child_sa;
81
82 /**
83 * Assigned logger. Use logger of IKE_SA.
84 */
85 logger_t *logger;
86 };
87
88 /**
89 * Implementation of private_ike_sa_established_t.build_sa_payload.
90 */
91 static status_t build_sa_payload(private_ike_sa_established_t *this, sa_payload_t *request, message_t *response)
92 {
93 proposal_t *proposal, *proposal_tmp;
94 linked_list_t *proposal_list;
95 sa_payload_t *sa_response;
96 chunk_t seed;
97 prf_plus_t *prf_plus;
98 status_t status;
99 connection_t *connection;
100 policy_t *policy;
101 u_int32_t reqid = 0;
102
103 /* prepare reply */
104 sa_response = sa_payload_create();
105
106 /* get proposals from request, and select one with ours */
107 policy = this->ike_sa->get_policy(this->ike_sa);
108 proposal_list = request->get_proposals(request);
109 this->logger->log(this->logger, CONTROL|LEVEL1, "Selecting proposals:");
110 proposal = policy->select_proposal(policy, proposal_list);
111 /* list is not needed anymore */
112 while (proposal_list->remove_last(proposal_list, (void**)&proposal_tmp) == SUCCESS)
113 {
114 proposal_tmp->destroy(proposal_tmp);
115 }
116 proposal_list->destroy(proposal_list);
117 /* do we have a proposal? */
118 if (proposal == NULL)
119 {
120 notify_payload_t *notify;
121 this->logger->log(this->logger, AUDIT, "CREATE_CHILD_SA request did not contain any proposals we accept. "
122 "Adding NO_PROPOSAL_CHOSEN notify");
123 /* add NO_PROPOSAL_CHOSEN and an empty SA payload */
124 notify = notify_payload_create_from_protocol_and_type(PROTO_IKE, NO_PROPOSAL_CHOSEN);
125 response->add_payload(response, (payload_t*)notify);
126 }
127 else
128 {
129 /* set up child sa */
130 seed = chunk_alloc(this->nonce_i.len + this->nonce_r.len);
131 memcpy(seed.ptr, this->nonce_i.ptr, this->nonce_i.len);
132 memcpy(seed.ptr + this->nonce_i.len, this->nonce_r.ptr, this->nonce_r.len);
133 prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
134 this->logger->log_chunk(this->logger, RAW|LEVEL2, "Rekey seed", seed);
135 chunk_free(&seed);
136 chunk_free(&this->nonce_i);
137 chunk_free(&this->nonce_r);
138
139 policy = this->ike_sa->get_policy(this->ike_sa);
140 connection = this->ike_sa->get_connection(this->ike_sa);
141 if (this->old_child_sa)
142 { /* reuse old reqid if we are rekeying */
143 reqid = this->old_child_sa->get_reqid(this->old_child_sa);
144 }
145 this->child_sa = child_sa_create(reqid,
146 connection->get_my_host(connection),
147 connection->get_other_host(connection),
148 policy->get_soft_lifetime(policy),
149 policy->get_hard_lifetime(policy));
150
151 status = this->child_sa->add(this->child_sa, proposal, prf_plus);
152 prf_plus->destroy(prf_plus);
153 if (status != SUCCESS)
154 {
155 this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA!");
156 sa_response->destroy(sa_response);
157 proposal->destroy(proposal);
158 return DESTROY_ME;
159 }
160
161 /* add proposal to sa payload */
162 sa_response->add_proposal(sa_response, proposal);
163 proposal->destroy(proposal);
164 }
165 response->add_payload(response, (payload_t*)sa_response);
166 return SUCCESS;
167 }
168
169 /**
170 * Implementation of private_ike_sa_established_t.build_ts_payload.
171 */
172 static status_t build_ts_payload(private_ike_sa_established_t *this, bool ts_initiator, ts_payload_t *request, message_t* response)
173 {
174 linked_list_t *ts_received, *ts_selected;
175 traffic_selector_t *ts;
176 status_t status = SUCCESS;
177 ts_payload_t *ts_response;
178 policy_t *policy;
179
180 policy = this->ike_sa->get_policy(this->ike_sa);
181
182 /* build a reply payload with selected traffic selectors */
183 ts_received = request->get_traffic_selectors(request);
184 /* select ts depending on payload type */
185 if (ts_initiator)
186 {
187 ts_selected = policy->select_other_traffic_selectors(policy, ts_received);
188 this->other_ts = ts_selected;
189 }
190 else
191 {
192 ts_selected = policy->select_my_traffic_selectors(policy, ts_received);
193 this->my_ts = ts_selected;
194 }
195
196 ts_response = ts_payload_create_from_traffic_selectors(ts_initiator, ts_selected);
197 response->add_payload(response, (payload_t*)ts_response);
198
199 /* add notify if traffic selectors do not match */
200 if (!ts_initiator &&
201 (ts_selected->get_count(ts_selected) == 0 || this->other_ts->get_count(this->other_ts) == 0))
202 {
203 notify_payload_t *notify;
204
205 this->logger->log(this->logger, AUDIT, "IKE_AUTH request did not contain any traffic selectors we accept. "
206 "Adding TS_UNACCEPTABLE notify");
207
208 notify = notify_payload_create_from_protocol_and_type(0, TS_UNACCEPTABLE);
209 response->add_payload(response, (payload_t*)notify);
210 }
211
212 /* cleanup */
213 while (ts_received->remove_last(ts_received, (void**)&ts) == SUCCESS)
214 {
215 ts->destroy(ts);
216 }
217 ts_received->destroy(ts_received);
218
219 return status;
220 }
221
222 /**
223 * Implementation of private_ike_sa_established_t.build_nonce_payload.
224 */
225 static status_t build_nonce_payload(private_ike_sa_established_t *this, nonce_payload_t *nonce_request, message_t *response)
226 {
227 nonce_payload_t *nonce_payload;
228 randomizer_t *randomizer;
229 status_t status;
230
231 randomizer = this->ike_sa->get_randomizer(this->ike_sa);
232 status = randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_SIZE, &this->nonce_r);
233 if (status != SUCCESS)
234 {
235 return status;
236 }
237 nonce_payload = nonce_payload_create();
238 nonce_payload->set_nonce(nonce_payload, this->nonce_r);
239
240 response->add_payload(response,(payload_t *) nonce_payload);
241
242 this->nonce_i = nonce_request->get_nonce(nonce_request);
243
244 return SUCCESS;
245 }
246
247 /**
248 * Process a CREATE_CHILD_SA request
249 */
250 static status_t process_create_child_sa(private_ike_sa_established_t *this, message_t *request, message_t *response)
251 {
252 ts_payload_t *tsi_request = NULL, *tsr_request = NULL;
253 sa_payload_t *sa_request = NULL;
254 nonce_payload_t *nonce_request = NULL;
255 notify_payload_t *notify = NULL;
256 iterator_t *payloads;
257 status_t status;
258
259 /* iterate over incoming payloads. Message is verified, we can be sure there are the required payloads */
260 payloads = request->get_payload_iterator(request);
261 while (payloads->has_next(payloads))
262 {
263 payload_t *payload;
264 payloads->current(payloads, (void**)&payload);
265
266 switch (payload->get_type(payload))
267 {
268 case SECURITY_ASSOCIATION:
269 {
270 sa_request = (sa_payload_t*)payload;
271 break;
272 }
273 case TRAFFIC_SELECTOR_INITIATOR:
274 {
275 tsi_request = (ts_payload_t*)payload;
276 break;
277 }
278 case TRAFFIC_SELECTOR_RESPONDER:
279 {
280 tsr_request = (ts_payload_t*)payload;
281 break;
282 }
283 case NONCE:
284 {
285 nonce_request = (nonce_payload_t*)payload;
286 break;
287 }
288 case KEY_EXCHANGE:
289 {
290 /* we currently do not support a diffie hellman exchange
291 * for CHILD_SAs. */
292 u_int16_t no_group[1];
293 no_group[0] = htons(MODP_NONE);
294 chunk_t no_group_chunk = chunk_from_buf((u_int8_t*)no_group);
295 this->ike_sa->send_notify(this->ike_sa, CREATE_CHILD_SA, INVALID_KE_PAYLOAD, no_group_chunk);
296 payloads->destroy(payloads);
297 return FAILED;
298 }
299 case NOTIFY:
300 {
301 notify = (notify_payload_t*)payload;
302 break;
303 }
304 default:
305 {
306 this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring payload %s (%d)",
307 mapping_find(payload_type_m, payload->get_type(payload)), payload->get_type(payload));
308 break;
309 }
310 }
311 }
312 /* iterator can be destroyed */
313 payloads->destroy(payloads);
314
315 /* check if we have all payloads */
316 if (!(sa_request && nonce_request && tsi_request && tsr_request))
317 {
318 this->logger->log(this->logger, AUDIT, "CREATE_CHILD_SA request did not contain all required payloads. Ignored");
319 return FAILED;
320 }
321
322 if (notify && notify->get_notify_message_type(notify) == REKEY_SA)
323 {
324 u_int32_t spi = notify->get_spi(notify);
325 this->old_child_sa = this->ike_sa->get_child_sa(this->ike_sa, spi);
326 this->logger->log(this->logger, CONTROL, "Rekeying CHILD_SA with SPI 0x%x", spi);
327 }
328 else
329 {
330 this->logger->log(this->logger, CONTROL, "Create new CHILD_SA");
331 }
332
333 /* build response */
334 this->ike_sa->build_message(this->ike_sa, CREATE_CHILD_SA, FALSE, &response);
335
336 /* add payloads to it */
337 status = build_nonce_payload(this, nonce_request, response);
338 if (status != SUCCESS)
339 {
340 response->destroy(response);
341 return status;
342 }
343 status = build_sa_payload(this, sa_request, response);
344 if (status != SUCCESS)
345 {
346 response->destroy(response);
347 return status;
348 }
349 status = build_ts_payload(this, TRUE, tsi_request, response);
350 if (status != SUCCESS)
351 {
352 response->destroy(response);
353 return status;
354 }
355 status = build_ts_payload(this, FALSE, tsr_request, response);
356 if (status != SUCCESS)
357 {
358 response->destroy(response);
359 return status;
360 }
361
362 status = this->ike_sa->send_response(this->ike_sa, response);
363 /* message can now be sent (must not be destroyed) */
364 if (status != SUCCESS)
365 {
366 this->logger->log(this->logger, AUDIT, "Unable to send CREATE_CHILD_SA reply. Ignored");
367 response->destroy(response);
368 return FAILED;
369 }
370
371 /* install child SA policies */
372 if (!this->child_sa)
373 {
374 this->logger->log(this->logger, ERROR, "Proposal negotiation failed, no CHILD_SA built");
375 }
376 else if (this->my_ts->get_count(this->my_ts) == 0 || this->other_ts->get_count(this->other_ts) == 0)
377 {
378 this->logger->log(this->logger, ERROR, "Traffic selector negotiation failed, no CHILD_SA built");
379 this->child_sa->destroy(this->child_sa);
380 this->child_sa = NULL;
381 }
382 else
383 {
384 status = this->child_sa->add_policies(this->child_sa, this->my_ts, this->other_ts);
385 if (status != SUCCESS)
386 {
387 this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA policy!");
388 }
389 if (this->old_child_sa)
390 { /* mark old child sa as rekeyed */
391 this->old_child_sa->set_rekeyed(this->old_child_sa);
392 }
393 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
394 }
395
396 return SUCCESS;
397 }
398
399
400 /**
401 * Process an informational request
402 */
403 static status_t process_informational(private_ike_sa_established_t *this, message_t *request, message_t *response)
404 {
405 delete_payload_t *delete_request = NULL;
406 iterator_t *payloads = request->get_payload_iterator(request);
407
408 while (payloads->has_next(payloads))
409 {
410 payload_t *payload;
411 payloads->current(payloads, (void**)&payload);
412
413 switch (payload->get_type(payload))
414 {
415 case DELETE:
416 {
417 delete_request = (delete_payload_t *) payload;
418 break;
419 }
420 default:
421 {
422 this->logger->log(this->logger, ERROR|LEVEL1, "Ignoring Payload %s (%d)",
423 mapping_find(payload_type_m, payload->get_type(payload)),
424 payload->get_type(payload));
425 break;
426 }
427 }
428 }
429 /* iterator can be destroyed */
430 payloads->destroy(payloads);
431
432 if (delete_request)
433 {
434 if (delete_request->get_protocol_id(delete_request) == PROTO_IKE)
435 {
436 this->logger->log(this->logger, CONTROL, "DELETE request for IKE_SA received");
437 /* switch to delete_ike_sa_requested. This is not absolutly correct, but we
438 * allow the clean destruction of an SA only in this state. */
439 this->ike_sa->set_new_state(this->ike_sa, (state_t*)delete_ike_sa_requested_create(this->ike_sa));
440 this->public.state_interface.destroy(&(this->public.state_interface));
441 this->ike_sa->send_response(this->ike_sa, response);
442 return DESTROY_ME;
443 }
444 else
445 {
446 iterator_t *iterator;
447 delete_payload_t *delete_response = delete_payload_create(delete_request->get_protocol_id(delete_request));
448 iterator = delete_request->create_spi_iterator(delete_request);
449 while (iterator->has_next(iterator))
450 {
451 u_int32_t spi;
452 iterator->current(iterator, (void**)&spi);
453 this->logger->log(this->logger, CONTROL, "DELETE request for CHILD_SA with SPI 0x%x received", spi);
454 spi = this->ike_sa->destroy_child_sa(this->ike_sa, spi);
455 if (spi)
456 {
457 delete_response->add_spi(delete_response, spi);
458 }
459 }
460 iterator->destroy(iterator);
461 response->add_payload(response, (payload_t*)delete_response);
462 }
463 }
464
465 if (this->ike_sa->send_response(this->ike_sa, response) != SUCCESS)
466 {
467 /* something is seriously wrong, kill connection */
468 this->logger->log(this->logger, AUDIT, "Unable to send reply. Deleting IKE_SA");
469 response->destroy(response);
470 return DESTROY_ME;
471 }
472 return SUCCESS;
473 }
474
475 /**
476 * Implements state_t.process_message
477 */
478 static status_t process_message(private_ike_sa_established_t *this, message_t *message)
479 {
480 ike_sa_id_t *ike_sa_id;
481 message_t *response;
482 crypter_t *crypter;
483 signer_t *signer;
484 status_t status;
485
486 /* only requests are allowed, responses are handled in other state */
487 if (!message->get_request(message))
488 {
489 this->logger->log(this->logger, ERROR|LEVEL1,
490 "Response not handled in state ike_sa_established");
491 return FAILED;
492 }
493
494 /* get signer for verification and crypter for decryption */
495 ike_sa_id = this->ike_sa->public.get_id(&this->ike_sa->public);
496 if (!ike_sa_id->is_initiator(ike_sa_id))
497 {
498 crypter = this->ike_sa->get_crypter_initiator(this->ike_sa);
499 signer = this->ike_sa->get_signer_initiator(this->ike_sa);
500 }
501 else
502 {
503 crypter = this->ike_sa->get_crypter_responder(this->ike_sa);
504 signer = this->ike_sa->get_signer_responder(this->ike_sa);
505 }
506
507 /* parse incoming message */
508 status = message->parse_body(message, crypter, signer);
509 if (status != SUCCESS)
510 {
511 this->logger->log(this->logger, AUDIT, "%s request decryption failed. Ignoring message",
512 mapping_find(exchange_type_m, message->get_exchange_type(message)));
513 return status;
514 }
515
516 /* prepare a reply of the same type */
517 this->ike_sa->build_message(this->ike_sa, message->get_exchange_type(message), FALSE, &response);
518
519 /* handle the different message types in their functions */
520 switch (message->get_exchange_type(message))
521 {
522 case INFORMATIONAL:
523 status = process_informational(this, message, response);
524 break;
525 case CREATE_CHILD_SA:
526 status = process_create_child_sa(this, message, response);
527 break;
528 default:
529 this->logger->log(this->logger, ERROR | LEVEL1,
530 "Message of type %s not supported in state ike_sa_established",
531 mapping_find(exchange_type_m, message->get_exchange_type(message)));
532 status = NOT_SUPPORTED;
533 }
534 return status;
535 }
536
537 /**
538 * Implementation of state_t.get_state.
539 */
540 static ike_sa_state_t get_state(private_ike_sa_established_t *this)
541 {
542 return IKE_SA_ESTABLISHED;
543 }
544
545 /**
546 * Implementation of state_t.get_state
547 */
548 static void destroy(private_ike_sa_established_t *this)
549 {
550 chunk_free(&this->nonce_i);
551 chunk_free(&this->nonce_r);
552 free(this);
553 }
554
555 /*
556 * Described in header.
557 */
558 ike_sa_established_t *ike_sa_established_create(protected_ike_sa_t *ike_sa)
559 {
560 private_ike_sa_established_t *this = malloc_thing(private_ike_sa_established_t);
561
562 /* interface functions */
563 this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *)) process_message;
564 this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state;
565 this->public.state_interface.destroy = (void (*) (state_t *)) destroy;
566
567 /* private data */
568 this->ike_sa = ike_sa;
569 this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
570 this->nonce_i = CHUNK_INITIALIZER;
571 this->nonce_r = CHUNK_INITIALIZER;
572 this->old_child_sa = NULL;
573
574 return &(this->public);
575 }