2 * @file ike_sa_init_requested.c
4 * @brief Implementation of ike_sa_init_requested_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
23 #include "ike_sa_init_requested.h"
26 #include <encoding/payloads/sa_payload.h>
27 #include <encoding/payloads/ke_payload.h>
28 #include <encoding/payloads/nonce_payload.h>
29 #include <encoding/payloads/notify_payload.h>
30 #include <encoding/payloads/id_payload.h>
31 #include <encoding/payloads/auth_payload.h>
32 #include <encoding/payloads/ts_payload.h>
33 #include <crypto/diffie_hellman.h>
34 #include <sa/states/ike_auth_requested.h>
35 #include <sa/states/initiator_init.h>
36 #include <sa/authenticator.h>
39 typedef struct private_ike_sa_init_requested_t private_ike_sa_init_requested_t
;
42 * Private data of a ike_sa_init_requested_t object.
45 struct private_ike_sa_init_requested_t
{
47 * Public interface of an ike_sa_init_requested_t object.
49 ike_sa_init_requested_t
public;
54 protected_ike_sa_t
*ike_sa
;
57 * Diffie Hellman object used to compute shared secret.
59 diffie_hellman_t
*diffie_hellman
;
69 chunk_t received_nonce
;
77 * Packet data of ike_sa_init request
79 chunk_t ike_sa_init_request_data
;
82 * Created child sa, if any
89 * Is logger of ike_sa!
95 * Process NONCE payload of IKE_SA_INIT response.
97 * @param this calling object
98 * @param nonce_payload NONCE payload to process
99 * @return SUCCESS in any case
101 status_t (*process_nonce_payload
) (private_ike_sa_init_requested_t
*this, nonce_payload_t
*nonce_payload
);
104 * Process SA payload of IKE_SA_INIT response.
106 * @param this calling object
107 * @param sa_payload SA payload to process
112 status_t (*process_sa_payload
) (private_ike_sa_init_requested_t
*this, sa_payload_t
*sa_payload
);
115 * Process KE payload of IKE_SA_INIT response.
117 * @param this calling object
118 * @param sa_payload KE payload to process
123 status_t (*process_ke_payload
) (private_ike_sa_init_requested_t
*this, ke_payload_t
*ke_payload
);
126 * Build ID payload for IKE_AUTH request.
128 * @param this calling object
129 * @param[out] id_payload buildet ID payload
130 * @param response created payload will be added to this message_t object
135 status_t (*build_id_payload
) (private_ike_sa_init_requested_t
*this,id_payload_t
**id_payload
, message_t
*response
);
138 * Build IDr payload for IKE_AUTH request.
140 * Only built when the ID of the responder contains no wildcards.
142 * @param this calling object
143 * @param response created payload will be added to this message_t object
148 status_t (*build_idr_payload
) (private_ike_sa_init_requested_t
*this, message_t
*response
);
151 * Build AUTH payload for IKE_AUTH request.
153 * @param this calling object
154 * @param my_id_payload buildet ID payload
155 * @param response created payload will be added to this message_t object
160 status_t (*build_auth_payload
) (private_ike_sa_init_requested_t
*this,id_payload_t
*my_id_payload
, message_t
*response
);
163 * Build SA payload for IKE_AUTH request.
165 * @param this calling object
166 * @param response created payload will be added to this message_t object
171 status_t (*build_sa_payload
) (private_ike_sa_init_requested_t
*this, message_t
*response
);
174 * Build TSi payload for IKE_AUTH request.
176 * @param this calling object
177 * @param response created payload will be added to this message_t object
182 status_t (*build_tsi_payload
) (private_ike_sa_init_requested_t
*this, message_t
*response
);
185 * Build TSr payload for IKE_AUTH request.
187 * @param this calling object
188 * @param response created payload will be added to this message_t object
193 status_t (*build_tsr_payload
) (private_ike_sa_init_requested_t
*this, message_t
*response
);
196 * Process a notify payload and react.
198 * @param this calling object
199 * @param notify_payload notify_payload to handle
201 status_t (*process_notify_payload
) (private_ike_sa_init_requested_t
*this, notify_payload_t
*notify_payload
);
204 * Destroy function called internally of this class after state change to
205 * state IKE_AUTH_REQUESTED succeeded.
207 * This destroy function does not destroy objects which were passed to the new state.
209 * @param this calling object
211 void (*destroy_after_state_change
) (private_ike_sa_init_requested_t
*this);
215 * Implementation of state_t.process_message.
217 static status_t
process_message(private_ike_sa_init_requested_t
*this, message_t
*ike_sa_init_reply
)
219 ike_auth_requested_t
*next_state
;
220 chunk_t ike_sa_init_reply_data
;
221 sa_payload_t
*sa_payload
= NULL
;
222 ke_payload_t
*ke_payload
= NULL
;
223 id_payload_t
*id_payload
= NULL
;
224 nonce_payload_t
*nonce_payload
= NULL
;
225 u_int64_t responder_spi
;
226 ike_sa_id_t
*ike_sa_id
;
227 iterator_t
*payloads
;
229 connection_t
*connection
;
236 * In this state a reply message of type IKE_SA_INIT is expected:
238 * <-- HDR, SAr1, KEr, Nr, [CERTREQ]
243 if (ike_sa_init_reply
->get_exchange_type(ike_sa_init_reply
) != IKE_SA_INIT
)
245 this->logger
->log(this->logger
, ERROR
| LEVEL1
, "Message of type %s not supported in state ike_sa_init_requested",
246 mapping_find(exchange_type_m
,ike_sa_init_reply
->get_exchange_type(ike_sa_init_reply
)));
250 if (ike_sa_init_reply
->get_request(ike_sa_init_reply
))
252 this->logger
->log(this->logger
, ERROR
| LEVEL1
, "IKE_SA_INIT requests not allowed state ike_sa_init_responded");
256 /* parse incoming message */
257 status
= ike_sa_init_reply
->parse_body(ike_sa_init_reply
, NULL
, NULL
);
258 if (status
!= SUCCESS
)
260 this->logger
->log(this->logger
, ERROR
| LEVEL1
, "IKE_SA_INIT reply parsing faild. Ignoring message");
264 /* because we are original initiator we have to update the responder SPI to the new one */
265 responder_spi
= ike_sa_init_reply
->get_responder_spi(ike_sa_init_reply
);
266 if (responder_spi
== 0)
268 this->logger
->log(this->logger
, ERROR
| LEVEL1
, "IKE_SA_INIT reply contained a SPI of zero");
271 ike_sa_id
= this->ike_sa
->public.get_id(&(this->ike_sa
->public));
272 ike_sa_id
->set_responder_spi(ike_sa_id
,responder_spi
);
274 /* Iterate over all payloads.
276 * The message is allready checked for the right payload types.
278 payloads
= ike_sa_init_reply
->get_payload_iterator(ike_sa_init_reply
);
279 while (payloads
->has_next(payloads
))
282 payloads
->current(payloads
, (void**)&payload
);
284 switch (payload
->get_type(payload
))
286 case SECURITY_ASSOCIATION
:
288 sa_payload
= (sa_payload_t
*)payload
;
293 ke_payload
= (ke_payload_t
*)payload
;
298 nonce_payload
= (nonce_payload_t
*)payload
;
303 notify_payload_t
*notify_payload
= (notify_payload_t
*) payload
;
305 status
= this->process_notify_payload(this, notify_payload
);
306 if (status
!= SUCCESS
)
308 payloads
->destroy(payloads
);
315 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "Ignoring payload %s (%d)",
316 mapping_find(payload_type_m
, payload
->get_type(payload
)), payload
->get_type(payload
));
323 payloads
->destroy(payloads
);
325 if (!(nonce_payload
&& sa_payload
&& ke_payload
))
327 this->logger
->log(this->logger
, AUDIT
, "IKE_SA_INIT reply did not contain all required payloads. Deleting IKE_SA");
331 status
= this->process_nonce_payload (this,nonce_payload
);
332 if (status
!= SUCCESS
)
337 status
= this->process_sa_payload (this,sa_payload
);
338 if (status
!= SUCCESS
)
343 status
= this->process_ke_payload (this,ke_payload
);
344 if (status
!= SUCCESS
)
349 /* derive all the keys used in the IKE_SA */
350 status
= this->ike_sa
->build_transforms(this->ike_sa
, this->proposal
, this->diffie_hellman
, this->sent_nonce
, this->received_nonce
);
351 if (status
!= SUCCESS
)
353 this->logger
->log(this->logger
, AUDIT
, "Transform objects could not be created from selected proposal. Deleting IKE_SA");
357 /* apply the address on wich we really received the packet */
358 connection
= this->ike_sa
->get_connection(this->ike_sa
);
359 me
= ike_sa_init_reply
->get_destination(ike_sa_init_reply
);
360 connection
->update_my_host(connection
, me
->clone(me
));
361 policy
= this->ike_sa
->get_policy(this->ike_sa
);
362 policy
->update_my_ts(policy
, me
);
364 /* build empty message */
365 this->ike_sa
->build_message(this->ike_sa
, IKE_AUTH
, TRUE
, &request
);
367 status
= this->build_id_payload(this, &id_payload
, request
);
368 if (status
!= SUCCESS
)
370 request
->destroy(request
);
373 status
= this->build_idr_payload(this, request
);
374 if (status
!= SUCCESS
)
376 request
->destroy(request
);
379 status
= this->build_auth_payload(this, (id_payload_t
*)id_payload
, request
);
380 if (status
!= SUCCESS
)
382 request
->destroy(request
);
385 status
= this->build_sa_payload(this, request
);
386 if (status
!= SUCCESS
)
388 request
->destroy(request
);
391 status
= this->build_tsi_payload(this, request
);
392 if (status
!= SUCCESS
)
394 request
->destroy(request
);
397 status
= this->build_tsr_payload(this, request
);
398 if (status
!= SUCCESS
)
400 request
->destroy(request
);
404 /* message can now be sent (must not be destroyed) */
405 status
= this->ike_sa
->send_request(this->ike_sa
, request
);
406 if (status
!= SUCCESS
)
408 this->logger
->log(this->logger
, AUDIT
, "Unable to send IKE_AUTH request. Deleting IKE_SA");
409 request
->destroy(request
);
413 this->ike_sa
->set_last_replied_message_id(this->ike_sa
,ike_sa_init_reply
->get_message_id(ike_sa_init_reply
));
415 ike_sa_init_reply_data
= ike_sa_init_reply
->get_packet_data(ike_sa_init_reply
);
417 /* state can now be changed */
418 next_state
= ike_auth_requested_create(this->ike_sa
, this->sent_nonce
, this->received_nonce
,
419 ike_sa_init_reply_data
, this->child_sa
);
420 this->ike_sa
->set_new_state(this->ike_sa
,(state_t
*) next_state
);
422 this->destroy_after_state_change(this);
428 * Implementation of private_ike_sa_init_requested_t.process_nonce_payload.
430 status_t
process_nonce_payload (private_ike_sa_init_requested_t
*this, nonce_payload_t
*nonce_payload
)
432 free(this->received_nonce
.ptr
);
433 this->received_nonce
= nonce_payload
->get_nonce(nonce_payload
);
439 * Implementation of private_ike_sa_init_requested_t.process_sa_payload.
441 status_t
process_sa_payload (private_ike_sa_init_requested_t
*this, sa_payload_t
*sa_payload
)
443 proposal_t
*proposal
;
444 linked_list_t
*proposal_list
;
445 connection_t
*connection
;
447 connection
= this->ike_sa
->get_connection(this->ike_sa
);
449 /* get the list of selected proposals, the peer has to select only one proposal */
450 proposal_list
= sa_payload
->get_proposals (sa_payload
);
451 if (proposal_list
->get_count(proposal_list
) != 1)
453 this->logger
->log(this->logger
, AUDIT
, "IKE_SA_INIT response did not contain a single proposal. Deleting IKE_SA");
454 while (proposal_list
->remove_last(proposal_list
, (void**)&proposal
) == SUCCESS
)
456 proposal
->destroy(proposal
);
458 proposal_list
->destroy(proposal_list
);
462 /* we have to re-check if the others selection is valid */
463 this->proposal
= connection
->select_proposal(connection
, proposal_list
);
464 while (proposal_list
->remove_last(proposal_list
, (void**)&proposal
) == SUCCESS
)
466 proposal
->destroy(proposal
);
468 proposal_list
->destroy(proposal_list
);
470 if (this->proposal
== NULL
)
472 this->logger
->log(this->logger
, AUDIT
, "IKE_SA_INIT response contained selected proposal we did not offer. Deleting IKE_SA");
480 * Implementation of private_ike_sa_init_requested_t.process_ke_payload.
482 status_t
process_ke_payload (private_ike_sa_init_requested_t
*this, ke_payload_t
*ke_payload
)
484 this->diffie_hellman
->set_other_public_value(this->diffie_hellman
, ke_payload
->get_key_exchange_data(ke_payload
));
490 * Implementation of private_ike_sa_init_requested_t.build_id_payload.
492 static status_t
build_id_payload (private_ike_sa_init_requested_t
*this,id_payload_t
**id_payload
, message_t
*request
)
495 id_payload_t
*new_id_payload
;
496 identification_t
*identification
;
498 policy
= this->ike_sa
->get_policy(this->ike_sa
);
499 identification
= policy
->get_my_id(policy
);
500 new_id_payload
= id_payload_create_from_identification(TRUE
, identification
);
502 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "Add ID payload to message");
503 request
->add_payload(request
,(payload_t
*) new_id_payload
);
505 *id_payload
= new_id_payload
;
511 * Implementation of private_ike_sa_init_requested_t.build_idr_payload.
513 static status_t
build_idr_payload (private_ike_sa_init_requested_t
*this, message_t
*request
)
516 id_payload_t
*idr_payload
;
517 identification_t
*identification
;
519 policy
= this->ike_sa
->get_policy(this->ike_sa
);
520 identification
= policy
->get_other_id(policy
);
521 if (!identification
->contains_wildcards(identification
))
523 idr_payload
= id_payload_create_from_identification(FALSE
, identification
);
525 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "Add IDr payload to message");
526 request
->add_payload(request
,(payload_t
*) idr_payload
);
532 * Implementation of private_ike_sa_init_requested_t.build_auth_payload.
534 static status_t
build_auth_payload (private_ike_sa_init_requested_t
*this, id_payload_t
*my_id_payload
, message_t
*request
)
536 authenticator_t
*authenticator
;
537 auth_payload_t
*auth_payload
;
540 authenticator
= authenticator_create(this->ike_sa
);
541 status
= authenticator
->compute_auth_data(authenticator
,&auth_payload
,this->ike_sa_init_request_data
,this->received_nonce
,my_id_payload
,TRUE
);
542 authenticator
->destroy(authenticator
);
544 if (status
!= SUCCESS
)
546 this->logger
->log(this->logger
, AUDIT
, "Could not generate AUTH data for IKE_AUTH request. Deleting IKE_SA");
550 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "Add AUTH payload to message");
551 request
->add_payload(request
,(payload_t
*) auth_payload
);
557 * Implementation of private_ike_sa_init_requested_t.build_sa_payload.
559 static status_t
build_sa_payload (private_ike_sa_init_requested_t
*this, message_t
*request
)
561 linked_list_t
*proposal_list
;
562 sa_payload_t
*sa_payload
;
564 connection_t
*connection
;
566 /* get proposals form config, add to payload */
567 policy
= this->ike_sa
->get_policy(this->ike_sa
);
568 proposal_list
= policy
->get_proposals(policy
);
570 connection
= this->ike_sa
->get_connection(this->ike_sa
);
571 this->child_sa
= child_sa_create(connection
->get_my_host(connection
),
572 connection
->get_other_host(connection
));
573 if (this->child_sa
->alloc(this->child_sa
, proposal_list
) != SUCCESS
)
575 this->logger
->log(this->logger
, AUDIT
, "Could not install CHILD_SA! Deleting IKE_SA");
579 sa_payload
= sa_payload_create_from_proposal_list(proposal_list
);
581 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "Add SA payload to message");
582 request
->add_payload(request
,(payload_t
*) sa_payload
);
588 * Implementation of private_ike_sa_init_requested_t.build_tsi_payload.
590 static status_t
build_tsi_payload (private_ike_sa_init_requested_t
*this, message_t
*request
)
592 linked_list_t
*ts_list
;
593 ts_payload_t
*ts_payload
;
596 policy
= this->ike_sa
->get_policy(this->ike_sa
);
597 ts_list
= policy
->get_my_traffic_selectors(policy
);
598 ts_payload
= ts_payload_create_from_traffic_selectors(TRUE
, ts_list
);
600 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "Add TSi payload to message");
601 request
->add_payload(request
,(payload_t
*) ts_payload
);
607 * Implementation of private_ike_sa_init_requested_t.build_tsr_payload.
609 static status_t
build_tsr_payload (private_ike_sa_init_requested_t
*this, message_t
*request
)
611 linked_list_t
*ts_list
;
612 ts_payload_t
*ts_payload
;
615 policy
= this->ike_sa
->get_policy(this->ike_sa
);
616 ts_list
= policy
->get_other_traffic_selectors(policy
);
617 ts_payload
= ts_payload_create_from_traffic_selectors(FALSE
, ts_list
);
619 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "Add TSr payload to message");
620 request
->add_payload(request
,(payload_t
*) ts_payload
);
626 * Implementation of private_ike_sa_init_requested_t.process_notify_payload.
628 static status_t
process_notify_payload(private_ike_sa_init_requested_t
*this, notify_payload_t
*notify_payload
)
630 notify_message_type_t notify_message_type
= notify_payload
->get_notify_message_type(notify_payload
);
632 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "Process notify type %s",
633 mapping_find(notify_message_type_m
, notify_message_type
));
635 switch (notify_message_type
)
637 case NO_PROPOSAL_CHOSEN
:
639 this->logger
->log(this->logger
, AUDIT
, "IKE_SA_INIT response contained a NO_PROPOSAL_CHOSEN notify. Deleting IKE_SA");
642 case INVALID_MAJOR_VERSION
:
644 this->logger
->log(this->logger
, AUDIT
, "IKE_SA_INIT response contained a INVALID_MAJOR_VERSION notify. Deleting IKE_SA");
647 case INVALID_KE_PAYLOAD
:
649 initiator_init_t
*initiator_init_state
;
651 diffie_hellman_group_t dh_group
, old_dh_group
;
652 connection_t
*connection
;
654 connection
= this->ike_sa
->get_connection(this->ike_sa
);
655 old_dh_group
= connection
->get_dh_group(connection
);
656 notify_data
= notify_payload
->get_notification_data(notify_payload
);
657 dh_group
= ntohs(*((u_int16_t
*)notify_data
.ptr
));
660 * We are very restrictive here: If the other didn't accept
661 * our DH group, and we do not accept his offer, continuation
665 this->logger
->log(this->logger
, AUDIT
, "Peer didn't accept %s, it requested %s!",
666 mapping_find(diffie_hellman_group_m
, old_dh_group
),
667 mapping_find(diffie_hellman_group_m
, dh_group
));
668 /* check if we can accept this dh group */
669 if (!connection
->check_dh_group(connection
, dh_group
))
671 this->logger
->log(this->logger
, AUDIT
,
672 "Peer does only accept DH group %s, which we do not accept! Aborting",
673 mapping_find(diffie_hellman_group_m
, dh_group
));
677 /* Going to change state back to initiator_init_t */
678 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "Create next state object");
679 initiator_init_state
= initiator_init_create(this->ike_sa
);
681 /* buffer of sent and received messages has to get reseted */
682 this->ike_sa
->reset_message_buffers(this->ike_sa
);
684 /* state can now be changed */
685 this->ike_sa
->set_new_state(this->ike_sa
,(state_t
*) initiator_init_state
);
687 /* state has NOW changed :-) */
688 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "Destroy old sate object");
689 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "Going to retry initialization of connection");
691 this->public.state_interface
.destroy(&(this->public.state_interface
));
692 if (initiator_init_state
->retry_initiate_connection (initiator_init_state
, dh_group
) != SUCCESS
)
701 * - In case of unknown error: IKE_SA gets destroyed.
702 * - In case of unknown status: logging
704 if (notify_message_type
< 16383)
706 this->logger
->log(this->logger
, AUDIT
, "IKE_SA_INIT reply contained an unknown notify error (%d). Deleting IKE_SA",
707 notify_message_type
);
712 this->logger
->log(this->logger
, CONTROL
, "IKE_SA_INIT reply contained an unknown notify (%d), ignored.",
713 notify_message_type
);
721 * Implementation of state_t.get_state.
723 static ike_sa_state_t
get_state(private_ike_sa_init_requested_t
*this)
725 return IKE_SA_INIT_REQUESTED
;
729 * Implementation of private_ike_sa_init_requested_t.destroy_after_state_change.
731 static void destroy_after_state_change (private_ike_sa_init_requested_t
*this)
733 this->diffie_hellman
->destroy(this->diffie_hellman
);
734 chunk_free(&(this->ike_sa_init_request_data
));
737 this->proposal
->destroy(this->proposal
);
743 * Implementation state_t.destroy.
745 static void destroy(private_ike_sa_init_requested_t
*this)
747 this->diffie_hellman
->destroy(this->diffie_hellman
);
748 free(this->sent_nonce
.ptr
);
749 free(this->received_nonce
.ptr
);
750 chunk_free(&(this->ike_sa_init_request_data
));
753 this->child_sa
->destroy(this->child_sa
);
757 this->proposal
->destroy(this->proposal
);
763 * Described in header.
765 ike_sa_init_requested_t
*ike_sa_init_requested_create(protected_ike_sa_t
*ike_sa
, diffie_hellman_t
*diffie_hellman
, chunk_t sent_nonce
,chunk_t ike_sa_init_request_data
)
767 private_ike_sa_init_requested_t
*this = malloc_thing(private_ike_sa_init_requested_t
);
769 /* interface functions */
770 this->public.state_interface
.process_message
= (status_t (*) (state_t
*,message_t
*)) process_message
;
771 this->public.state_interface
.get_state
= (ike_sa_state_t (*) (state_t
*)) get_state
;
772 this->public.state_interface
.destroy
= (void (*) (state_t
*)) destroy
;
774 /* private functions */
775 this->destroy_after_state_change
= destroy_after_state_change
;
776 this->process_nonce_payload
= process_nonce_payload
;
777 this->process_sa_payload
= process_sa_payload
;
778 this->process_ke_payload
= process_ke_payload
;
779 this->build_auth_payload
= build_auth_payload
;
780 this->build_tsi_payload
= build_tsi_payload
;
781 this->build_tsr_payload
= build_tsr_payload
;
782 this->build_id_payload
= build_id_payload
;
783 this->build_idr_payload
= build_idr_payload
;
784 this->build_sa_payload
= build_sa_payload
;
785 this->process_notify_payload
= process_notify_payload
;
788 this->ike_sa
= ike_sa
;
789 this->received_nonce
= CHUNK_INITIALIZER
;
790 this->logger
= logger_manager
->get_logger(logger_manager
, IKE_SA
);
791 this->diffie_hellman
= diffie_hellman
;
792 this->proposal
= NULL
;
793 this->sent_nonce
= sent_nonce
;
794 this->child_sa
= NULL
;
795 this->ike_sa_init_request_data
= ike_sa_init_request_data
;
797 return &(this->public);