34bc1dbda75f3cfd98722c73afcdc16282030873
[strongswan.git] / Source / charon / sa / states / ike_sa_init_responded.c
1 /**
2 * @file ike_sa_init_responded.c
3 *
4 * @brief State of a IKE_SA after responding to an IKE_SA_INIT request
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_sa_init_responded.h"
24
25 #include <utils/allocator.h>
26 #include <transforms/signers/signer.h>
27 #include <transforms/crypters/crypter.h>
28
29
30 typedef struct private_ike_sa_init_responded_t private_ike_sa_init_responded_t;
31
32 /**
33 * Private data of a ike_sa_init_responded_t object.
34 *
35 */
36 struct private_ike_sa_init_responded_t {
37 /**
38 * methods of the state_t interface
39 */
40 ike_sa_init_responded_t public;
41
42 /**
43 * Shared secret from DH-Exchange
44 *
45 * All needed secrets are derived from this shared secret and then passed to the next
46 * state of type ike_sa_established_t
47 */
48 chunk_t shared_secret;
49
50 /**
51 * Sent nonce used to calculate secrets
52 */
53 chunk_t received_nonce;
54
55 /**
56 * Sent nonce used to calculate secrets
57 */
58 chunk_t sent_nonce;
59
60 /**
61 * Assigned IKE_SA
62 */
63 protected_ike_sa_t *ike_sa;
64
65 /**
66 * Logger used to log data
67 *
68 * Is logger of ike_sa!
69 */
70 logger_t *logger;
71 };
72
73 /**
74 * Implements state_t.get_state
75 */
76 static status_t process_message(private_ike_sa_init_responded_t *this, message_t *message)
77 {
78 status_t status;
79 signer_t *signer;
80 crypter_t *crypter;
81 iterator_t *payloads;
82 exchange_type_t exchange_type;
83
84
85 exchange_type = message->get_exchange_type(message);
86 if (exchange_type != IKE_AUTH)
87 {
88 this->logger->log(this->logger, ERROR | MORE, "Message of type %s not supported in state ike_sa_init_responded",
89 mapping_find(exchange_type_m,exchange_type));
90 return FAILED;
91 }
92
93 if (!message->get_request(message))
94 {
95 this->logger->log(this->logger, ERROR | MORE, "Only requests of type IKE_AUTH supported in state ike_sa_init_responded");
96 return FAILED;
97 }
98
99
100 /* get signer for verification and crypter for decryption */
101 signer = this->ike_sa->get_signer_initiator(this->ike_sa);
102 crypter = this->ike_sa->get_crypter_initiator(this->ike_sa);
103
104 /* parse incoming message */
105 status = message->parse_body(message, crypter, signer);
106 if (status != SUCCESS)
107 {
108 this->logger->log(this->logger, ERROR | MORE, "Could not parse body of request message");
109 return status;
110 }
111
112 /* iterate over incoming payloads. We can be sure, the message contains only accepted payloads! */
113 payloads = message->get_payload_iterator(message);
114
115 while (payloads->has_next(payloads))
116 {
117 payload_t *payload;
118
119 /* get current payload */
120 payloads->current(payloads, (void**)&payload);
121
122 this->logger->log(this->logger, CONTROL|MORE, "Processing payload of type %s", mapping_find(payload_type_m, payload->get_type(payload)));
123 switch (payload->get_type(payload))
124 {
125 // case SECURITY_ASSOCIATION:
126 // {
127 // sa_payload_t *sa_payload = (sa_payload_t*)payload;
128 // iterator_t *suggested_proposals, *accepted_proposals;
129 // proposal_substructure_t *accepted_proposal;
130 //
131 // accepted_proposals = this->proposals->create_iterator(this->proposals, FALSE);
132 //
133 // /* get the list of suggested proposals */
134 // suggested_proposals = sa_payload->create_proposal_substructure_iterator(sa_payload, TRUE);
135 //
136 // /* now let the configuration-manager select a subset of the proposals */
137 // status = charon->configuration_manager->select_proposals_for_host(charon->configuration_manager,
138 // this->ike_sa->get_other_host(this->ike_sa), suggested_proposals, accepted_proposals);
139 // if (status != SUCCESS)
140 // {
141 // this->logger->log(this->logger, CONTROL | MORE, "No proposal of suggested proposals selected");
142 // suggested_proposals->destroy(suggested_proposals);
143 // accepted_proposals->destroy(accepted_proposals);
144 // payloads->destroy(payloads);
145 // return status;
146 // }
147 //
148 // /* iterators are not needed anymore */
149 // suggested_proposals->destroy(suggested_proposals);
150 //
151 // /* let the ike_sa create their own transforms from proposal informations */
152 // accepted_proposals->reset(accepted_proposals);
153 // /* TODO check for true*/
154 // accepted_proposals->has_next(accepted_proposals);
155 // status = accepted_proposals->current(accepted_proposals,(void **)&accepted_proposal);
156 // if (status != SUCCESS)
157 // {
158 // this->logger->log(this->logger, ERROR | MORE, "Accepted proposals not supported?!");
159 // accepted_proposals->destroy(accepted_proposals);
160 // payloads->destroy(payloads);
161 // return status;
162 // }
163 //
164 // status = this->ike_sa->create_transforms_from_proposal(this->ike_sa,accepted_proposal);
165 // accepted_proposals->destroy(accepted_proposals);
166 // if (status != SUCCESS)
167 // {
168 // this->logger->log(this->logger, ERROR | MORE, "Transform objects could not be created from selected proposal");
169 // payloads->destroy(payloads);
170 // return status;
171 // }
172 //
173 // this->logger->log(this->logger, CONTROL | MORE, "SA Payload processed");
174 // /* ok, we have what we need for sa_payload (proposals are stored in this->proposals)*/
175 // break;
176 // }
177
178 default:
179 {
180 this->logger->log(this->logger, ERROR | MORE, "Payload type not supported!");
181 payloads->destroy(payloads);
182 return NOT_SUPPORTED;
183 }
184 }
185 }
186 /* iterator can be destroyed */
187 payloads->destroy(payloads);
188
189
190
191 this->logger->log(this->logger, CONTROL | MORE, "Request successfully handled. Going to create reply.");
192
193 this->logger->log(this->logger, CONTROL | MOST, "Going to create nonce.");
194
195
196 return SUCCESS;
197 }
198
199 /**
200 * Implements state_t.get_state
201 */
202 static ike_sa_state_t get_state(private_ike_sa_init_responded_t *this)
203 {
204 return IKE_SA_INIT_RESPONDED;
205 }
206
207 /**
208 * Implements state_t.get_state
209 */
210 static void destroy(private_ike_sa_init_responded_t *this)
211 {
212 this->logger->log(this->logger, CONTROL | MORE, "Going to destroy ike_sa_init_responded_t state object");
213
214 this->logger->log(this->logger, CONTROL | MOST, "Destroy shared_secret");
215 allocator_free(this->shared_secret.ptr);
216
217 this->logger->log(this->logger, CONTROL | MOST, "Destroy sent nonce");
218 allocator_free(this->sent_nonce.ptr);
219
220 this->logger->log(this->logger, CONTROL | MOST, "Destroy received nonce");
221 allocator_free(this->received_nonce.ptr);
222
223 allocator_free(this);
224 }
225
226 /*
227 * Described in header.
228 */
229
230 ike_sa_init_responded_t *ike_sa_init_responded_create(protected_ike_sa_t *ike_sa, chunk_t shared_secret, chunk_t received_nonce, chunk_t sent_nonce)
231 {
232 private_ike_sa_init_responded_t *this = allocator_alloc_thing(private_ike_sa_init_responded_t);
233
234 /* interface functions */
235 this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *)) process_message;
236 this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state;
237 this->public.state_interface.destroy = (void (*) (state_t *)) destroy;
238
239 /* private data */
240 this->ike_sa = ike_sa;
241 this->logger = this->ike_sa->get_logger(this->ike_sa);
242 this->shared_secret = shared_secret;
243 this->received_nonce = received_nonce;
244 this->sent_nonce = sent_nonce;
245
246 return &(this->public);
247 }