2 * @file ike_auth_requested.c
4 * @brief Implementation of ike_auth_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_auth_requested.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 <transforms/signers/signer.h>
32 #include <transforms/crypters/crypter.h>
33 #include <sa/states/ike_sa_established.h>
35 typedef struct private_ike_auth_requested_t private_ike_auth_requested_t
;
38 * Private data of a ike_auth_requested_t object.
41 struct private_ike_auth_requested_t
{
43 * methods of the state_t interface
45 ike_auth_requested_t
public;
55 chunk_t received_nonce
;
60 protected_ike_sa_t
*ike_sa
;
63 * SA config, just a copy of the one stored in the ike_sa
65 sa_config_t
*sa_config
;
68 * Logger used to log data
70 * Is logger of ike_sa!
74 status_t (*process_idr_payload
) (private_ike_auth_requested_t
*this, id_payload_t
*idr_payload
);
75 status_t (*process_sa_payload
) (private_ike_auth_requested_t
*this, sa_payload_t
*sa_payload
);
76 status_t (*process_auth_payload
) (private_ike_auth_requested_t
*this, auth_payload_t
*auth_payload
);
77 status_t (*process_ts_payload
) (private_ike_auth_requested_t
*this, bool ts_initiator
, ts_payload_t
*ts_payload
);
83 * Implements state_t.process_message
85 static status_t
process_message(private_ike_auth_requested_t
*this, message_t
*request
)
91 exchange_type_t exchange_type
;
92 id_payload_t
*idr_payload
;
93 auth_payload_t
*auth_payload
;
94 sa_payload_t
*sa_payload
;
95 ts_payload_t
*tsi_payload
, *tsr_payload
;
99 exchange_type
= request
->get_exchange_type(request
);
100 if (exchange_type
!= IKE_AUTH
)
102 this->logger
->log(this->logger
, ERROR
| MORE
, "Message of type %s not supported in state ike_auth_requested",
103 mapping_find(exchange_type_m
,exchange_type
));
107 if (request
->get_request(request
))
109 this->logger
->log(this->logger
, ERROR
| MORE
, "Only responses of type IKE_AUTH supported in state ike_auth_requested");
113 /* get signer for verification and crypter for decryption */
114 signer
= this->ike_sa
->get_signer_responder(this->ike_sa
);
115 crypter
= this->ike_sa
->get_crypter_responder(this->ike_sa
);
117 /* parse incoming message */
118 status
= request
->parse_body(request
, crypter
, signer
);
119 if (status
!= SUCCESS
)
121 this->logger
->log(this->logger
, ERROR
| MORE
, "Could not parse body of request message");
125 this->sa_config
= this->ike_sa
->get_sa_config(this->ike_sa
);
127 /* iterate over incoming payloads. Message is verified, we can be sure there are the required payloads */
128 payloads
= request
->get_payload_iterator(request
);
129 while (payloads
->has_next(payloads
))
132 payloads
->current(payloads
, (void**)&payload
);
134 switch (payload
->get_type(payload
))
138 auth_payload
= (auth_payload_t
*)payload
;
143 idr_payload
= (id_payload_t
*)payload
;
146 case SECURITY_ASSOCIATION
:
148 sa_payload
= (sa_payload_t
*)payload
;
153 /* TODO handle cert payloads */
156 case TRAFFIC_SELECTOR_INITIATOR
:
158 tsi_payload
= (ts_payload_t
*)payload
;
161 case TRAFFIC_SELECTOR_RESPONDER
:
163 tsr_payload
= (ts_payload_t
*)payload
;
168 /* can't happen, since message is verified, notify's? */
173 /* iterator can be destroyed */
174 payloads
->destroy(payloads
);
177 /* add payloads to it */
178 status
= this->process_idr_payload(this, idr_payload
);
179 if (status
!= SUCCESS
)
181 this->logger
->log(this->logger
, ERROR
, "Processing idr payload failed");
184 status
= this->process_sa_payload(this, sa_payload
);
185 if (status
!= SUCCESS
)
187 this->logger
->log(this->logger
, ERROR
, "Processing sa payload failed");
190 status
= this->process_auth_payload(this, auth_payload
);
191 if (status
!= SUCCESS
)
193 this->logger
->log(this->logger
, ERROR
, "Processing auth payload failed");
196 status
= this->process_ts_payload(this, TRUE
, tsi_payload
);
197 if (status
!= SUCCESS
)
199 this->logger
->log(this->logger
, ERROR
, "Processing tsi payload failed");
202 status
= this->process_ts_payload(this, FALSE
, tsr_payload
);
203 if (status
!= SUCCESS
)
205 this->logger
->log(this->logger
, ERROR
, "Processing tsr payload failed");
209 this->logger
->log(this->logger
, CONTROL
| MORE
, "IKE_AUTH response successfully handled. IKE_SA established.");
211 /* create new state */
212 this->ike_sa
->set_new_state(this->ike_sa
, (state_t
*)ike_sa_established_create(this->ike_sa
));
218 * Implements private_ike_auth_requested_t.build_idr_payload
220 static status_t
process_idr_payload(private_ike_auth_requested_t
*this, id_payload_t
*idr_payload
)
222 identification_t
*other_id
, *configured_other_id
;
224 other_id
= idr_payload
->get_identification(idr_payload
);
226 configured_other_id
= this->sa_config
->get_other_id(this->sa_config
);
227 if (configured_other_id
)
229 if (!other_id
->equals(other_id
, configured_other_id
))
231 this->logger
->log(this->logger
, ERROR
, "IKE_AUTH reply didn't contain requested id");
236 /* TODO do we have to store other_id somewhere ? */
241 * Implements private_ike_auth_requested_t.build_sa_payload
243 static status_t
process_sa_payload(private_ike_auth_requested_t
*this, sa_payload_t
*sa_payload
)
245 child_proposal_t
*proposals
, *proposal_chosen
;
246 size_t proposal_count
;
249 /* dummy spis, until we have a child sa to request them */
250 u_int8_t ah_spi
[4] = {0x01, 0x02, 0x03, 0x04};
251 u_int8_t esp_spi
[4] = {0x05, 0x06, 0x07, 0x08};
253 /* check selected proposal */
254 status
= sa_payload
->get_child_proposals(sa_payload
, &proposals
, &proposal_count
);
255 if (status
!= SUCCESS
)
257 this->logger
->log(this->logger
, ERROR
, "responders sa payload contained no proposals");
260 if (proposal_count
> 1)
262 allocator_free(proposals
);
263 this->logger
->log(this->logger
, ERROR
, "responders sa payload contained more than one proposal");
267 proposal_chosen
= this->sa_config
->select_proposal(this->sa_config
, ah_spi
, esp_spi
, proposals
, proposal_count
);
268 if (proposal_chosen
== NULL
)
270 this->logger
->log(this->logger
, ERROR
, "responder selected an not offered proposal");
271 allocator_free(proposals
);
276 allocator_free(proposal_chosen
);
279 allocator_free(proposals
);
285 * Implements private_ike_auth_requested_t.build_auth_payload
287 static status_t
process_auth_payload(private_ike_auth_requested_t
*this, auth_payload_t
*auth_payload
)
289 /* TODO VERIFY auth here */
294 * Implements private_ike_auth_requested_t.build_ts_payload
296 static status_t
process_ts_payload(private_ike_auth_requested_t
*this, bool ts_initiator
, ts_payload_t
*ts_payload
)
298 traffic_selector_t
**ts_received
, **ts_selected
;
299 size_t ts_received_count
, ts_selected_count
;
300 status_t status
= SUCCESS
;
302 /* get ts form payload */
303 ts_received_count
= ts_payload
->get_traffic_selectors(ts_payload
, &ts_received
);
304 /* select ts depending on payload type */
307 ts_selected_count
= this->sa_config
->select_traffic_selectors_initiator(this->sa_config
, ts_received
, ts_received_count
, &ts_selected
);
311 ts_selected_count
= this->sa_config
->select_traffic_selectors_responder(this->sa_config
, ts_received
, ts_received_count
, &ts_selected
);
313 /* check if the responder selected valid proposals */
314 if (ts_selected_count
!= ts_received_count
)
316 this->logger
->log(this->logger
, ERROR
, "responder selected invalid traffic selectors");
321 while(ts_received_count
--)
323 traffic_selector_t
*ts
= *ts_received
+ ts_received_count
;
326 allocator_free(ts_received
);
327 while(ts_selected_count
--)
329 traffic_selector_t
*ts
= *ts_selected
+ ts_selected_count
;
332 allocator_free(ts_selected
);
336 * Implements state_t.get_state
338 static ike_sa_state_t
get_state(private_ike_auth_requested_t
*this)
340 return IKE_AUTH_REQUESTED
;
344 * Implements state_t.get_state
346 static void destroy(private_ike_auth_requested_t
*this)
348 allocator_free(this->sent_nonce
.ptr
);
349 allocator_free(this->received_nonce
.ptr
);
350 allocator_free(this);
354 * Described in header.
356 ike_auth_requested_t
*ike_auth_requested_create(protected_ike_sa_t
*ike_sa
, chunk_t sent_nonce
, chunk_t received_nonce
)
358 private_ike_auth_requested_t
*this = allocator_alloc_thing(private_ike_auth_requested_t
);
360 /* interface functions */
361 this->public.state_interface
.process_message
= (status_t (*) (state_t
*,message_t
*)) process_message
;
362 this->public.state_interface
.get_state
= (ike_sa_state_t (*) (state_t
*)) get_state
;
363 this->public.state_interface
.destroy
= (void (*) (state_t
*)) destroy
;
365 /* private functions */
367 this->process_idr_payload
= process_idr_payload
;
368 this->process_sa_payload
= process_sa_payload
;
369 this->process_auth_payload
= process_auth_payload
;
370 this->process_ts_payload
= process_ts_payload
;
373 this->ike_sa
= ike_sa
;
374 this->sent_nonce
= sent_nonce
;
375 this->received_nonce
= received_nonce
;
378 return &(this->public);