Set default IKE header initiator flag in IKEv2 only
[strongswan.git] / src / libcharon / encoding / payloads / ike_header.c
1 /*
2 * Copyright (C) 2007 Tobias Brunner
3 * Copyright (C) 2005-2006 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 /* offsetof macro */
19 #include <stddef.h>
20
21 #include "ike_header.h"
22
23 #include <encoding/payloads/encodings.h>
24
25
26 typedef struct private_ike_header_t private_ike_header_t;
27
28 /**
29 * Private data of an ike_header_t object.
30 */
31 struct private_ike_header_t {
32 /**
33 * Public interface.
34 */
35 ike_header_t public;
36
37 /**
38 * SPI of the initiator.
39 */
40 u_int64_t initiator_spi;
41
42 /**
43 * SPI of the responder.
44 */
45 u_int64_t responder_spi;
46
47 /**
48 * Next payload type.
49 */
50 u_int8_t next_payload;
51 /**
52 * IKE major version.
53 */
54 u_int8_t maj_version;
55
56 /**
57 * IKE minor version.
58 */
59 u_int8_t min_version;
60
61 /**
62 * Exchange type .
63 */
64 u_int8_t exchange_type;
65
66 /**
67 * Flags of the Message.
68 */
69 struct {
70 /**
71 * Sender is initiator of the associated IKE_SA_INIT-Exchange.
72 */
73 bool initiator;
74
75 /**
76 * Is protocol supporting higher version?
77 */
78 bool version;
79
80 /**
81 * TRUE, if this is a response, FALSE if its a Request.
82 */
83 bool response;
84
85 /**
86 * TRUE, if the packet is encrypted (IKEv1).
87 */
88 bool encryption;
89
90 /**
91 * TRUE, if the commit flag is set (IKEv1).
92 */
93 bool commit;
94
95 /**
96 * TRUE, if the auth only flag is set (IKEv1).
97 */
98 bool authonly;
99 } flags;
100
101 /**
102 * Reserved bits of IKE header
103 */
104 bool reserved[2];
105
106 /**
107 * Associated Message-ID.
108 */
109 u_int32_t message_id;
110
111 /**
112 * Length of the whole IKEv2-Message (header and all payloads).
113 */
114 u_int32_t length;
115 };
116
117 ENUM_BEGIN(exchange_type_names, ID_PROT, INFORMATIONAL_V1,
118 "ID_PROT",
119 "AUTH_ONLY",
120 "AGGRESSIVE",
121 "INFORMATIONAL_V1");
122 ENUM_NEXT(exchange_type_names, QUICK_MODE, IKE_SESSION_RESUME, INFORMATIONAL_V1,
123 "QUICK_MODE",
124 "NEW_GROUP_MODE",
125 "IKE_SA_INIT",
126 "IKE_AUTH",
127 "CREATE_CHILD_SA",
128 "INFORMATIONAL",
129 "IKE_SESSION_RESUME");
130 #ifdef ME
131 ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, IKE_SESSION_RESUME,
132 "ME_CONNECT");
133 ENUM_NEXT(exchange_type_names, EXCHANGE_TYPE_UNDEFINED,
134 EXCHANGE_TYPE_UNDEFINED, ME_CONNECT,
135 "EXCHANGE_TYPE_UNDEFINED");
136 #else
137 ENUM_NEXT(exchange_type_names, EXCHANGE_TYPE_UNDEFINED,
138 EXCHANGE_TYPE_UNDEFINED, IKE_SESSION_RESUME,
139 "EXCHANGE_TYPE_UNDEFINED");
140 #endif /* ME */
141 ENUM_END(exchange_type_names, EXCHANGE_TYPE_UNDEFINED);
142
143 /**
144 * Encoding rules to parse or generate a IKE-Header.
145 *
146 * The defined offsets are the positions in a object of type
147 * ike_header_t.
148 */
149 encoding_rule_t ike_header_encodings[] = {
150 /* 8 Byte SPI, stored in the field initiator_spi */
151 { IKE_SPI, offsetof(private_ike_header_t, initiator_spi) },
152 /* 8 Byte SPI, stored in the field responder_spi */
153 { IKE_SPI, offsetof(private_ike_header_t, responder_spi) },
154 /* 1 Byte next payload type, stored in the field next_payload */
155 { U_INT_8, offsetof(private_ike_header_t, next_payload) },
156 /* 4 Bit major version, stored in the field maj_version */
157 { U_INT_4, offsetof(private_ike_header_t, maj_version) },
158 /* 4 Bit minor version, stored in the field min_version */
159 { U_INT_4, offsetof(private_ike_header_t, min_version) },
160 /* 8 Bit for the exchange type */
161 { U_INT_8, offsetof(private_ike_header_t, exchange_type) },
162 /* 2 Bit reserved bits */
163 { RESERVED_BIT, offsetof(private_ike_header_t, reserved[0]) },
164 { RESERVED_BIT, offsetof(private_ike_header_t, reserved[1]) },
165 /* 6 flags */
166 { FLAG, offsetof(private_ike_header_t, flags.response) },
167 { FLAG, offsetof(private_ike_header_t, flags.version) },
168 { FLAG, offsetof(private_ike_header_t, flags.initiator) },
169 { FLAG, offsetof(private_ike_header_t, flags.authonly) },
170 { FLAG, offsetof(private_ike_header_t, flags.commit) },
171 { FLAG, offsetof(private_ike_header_t, flags.encryption)},
172 /* 4 Byte message id, stored in the field message_id */
173 { U_INT_32, offsetof(private_ike_header_t, message_id) },
174 /* 4 Byte length fied, stored in the field length */
175 { HEADER_LENGTH,offsetof(private_ike_header_t, length) },
176 };
177
178 /* 1 2 3
179 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
180 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
181 ! IKE_SA Initiator's SPI !
182 ! !
183 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
184 ! IKE_SA Responder's SPI !
185 ! !
186 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
187 ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags !
188 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
189 ! Message ID !
190 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
191 ! Length !
192 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
193 */
194
195 METHOD(payload_t, verify, status_t,
196 private_ike_header_t *this)
197 {
198 switch (this->exchange_type)
199 {
200 case ID_PROT:
201 case AGGRESSIVE:
202 if (this->message_id != 0)
203 {
204 return FAILED;
205 }
206 /* fall */
207 case AUTH_ONLY:
208 case INFORMATIONAL_V1:
209 case QUICK_MODE:
210 case NEW_GROUP_MODE:
211 if (this->maj_version != IKEV1_MAJOR_VERSION)
212 {
213 return FAILED;
214 }
215 break;
216 case IKE_SA_INIT:
217 case IKE_AUTH:
218 case CREATE_CHILD_SA:
219 case INFORMATIONAL:
220 case IKE_SESSION_RESUME:
221 #ifdef ME
222 case ME_CONNECT:
223 #endif /* ME */
224 if (this->maj_version != IKEV2_MAJOR_VERSION)
225 {
226 return FAILED;
227 }
228 break;
229 default:
230 /* unsupported exchange type */
231 return FAILED;
232 }
233 if (this->initiator_spi == 0)
234 {
235 #ifdef ME
236 if (this->exchange_type != INFORMATIONAL)
237 /* we allow zero spi for INFORMATIONAL exchanges,
238 * to allow connectivity checks */
239 #endif /* ME */
240 {
241 return FAILED;
242 }
243 }
244 return SUCCESS;
245 }
246
247 METHOD(payload_t, get_encoding_rules, void,
248 private_ike_header_t *this, encoding_rule_t **rules, size_t *rule_count)
249 {
250 *rules = ike_header_encodings;
251 *rule_count = sizeof(ike_header_encodings) / sizeof(encoding_rule_t);
252 }
253
254 METHOD(payload_t, get_type, payload_type_t,
255 private_ike_header_t *this)
256 {
257 return HEADER;
258 }
259
260 METHOD(payload_t, get_next_type, payload_type_t,
261 private_ike_header_t *this)
262 {
263 return this->next_payload;
264 }
265
266 METHOD(payload_t, set_next_type, void,
267 private_ike_header_t *this, payload_type_t type)
268 {
269 this->next_payload = type;
270 }
271
272 METHOD(payload_t, get_length, size_t,
273 private_ike_header_t *this)
274 {
275 return this->length;
276 }
277
278 METHOD(ike_header_t, get_initiator_spi, u_int64_t,
279 private_ike_header_t *this)
280 {
281 return this->initiator_spi;
282 }
283
284 METHOD(ike_header_t, set_initiator_spi, void,
285 private_ike_header_t *this, u_int64_t initiator_spi)
286 {
287 this->initiator_spi = initiator_spi;
288 }
289
290 METHOD(ike_header_t, get_responder_spi, u_int64_t,
291 private_ike_header_t *this)
292 {
293 return this->responder_spi;
294 }
295
296 METHOD(ike_header_t, set_responder_spi, void,
297 private_ike_header_t *this, u_int64_t responder_spi)
298 {
299 this->responder_spi = responder_spi;
300 }
301
302 METHOD(ike_header_t, get_maj_version, u_int8_t,
303 private_ike_header_t *this)
304 {
305 return this->maj_version;
306 }
307
308 METHOD(ike_header_t, set_maj_version, void,
309 private_ike_header_t *this, u_int8_t major)
310 {
311 this->maj_version = major;
312 }
313
314 METHOD(ike_header_t, get_min_version, u_int8_t,
315 private_ike_header_t *this)
316 {
317 return this->min_version;
318 }
319
320 METHOD(ike_header_t, set_min_version, void,
321 private_ike_header_t *this, u_int8_t minor)
322 {
323 this->min_version = minor;
324 }
325
326 METHOD(ike_header_t, get_response_flag, bool,
327 private_ike_header_t *this)
328 {
329 return this->flags.response;
330 }
331
332 METHOD(ike_header_t, set_response_flag, void,
333 private_ike_header_t *this, bool response)
334 {
335 this->flags.response = response;
336 }
337
338 METHOD(ike_header_t, get_version_flag, bool,
339 private_ike_header_t *this)
340 {
341 return this->flags.version;
342 }
343
344 METHOD(ike_header_t, set_version_flag, void,
345 private_ike_header_t *this, bool version)
346 {
347 this->flags.version = version;
348 }
349
350 METHOD(ike_header_t, get_initiator_flag, bool,
351 private_ike_header_t *this)
352 {
353 return this->flags.initiator;
354 }
355
356 METHOD(ike_header_t, set_initiator_flag, void,
357 private_ike_header_t *this, bool initiator)
358 {
359 this->flags.initiator = initiator;
360 }
361
362 METHOD(ike_header_t, get_encryption_flag, bool,
363 private_ike_header_t *this)
364 {
365 return this->flags.encryption;
366 }
367
368 METHOD(ike_header_t, set_encryption_flag, void,
369 private_ike_header_t *this, bool encryption)
370 {
371 this->flags.encryption = encryption;
372 }
373
374
375 METHOD(ike_header_t, get_commit_flag, bool,
376 private_ike_header_t *this)
377 {
378 return this->flags.commit;
379 }
380
381 METHOD(ike_header_t, set_commit_flag, void,
382 private_ike_header_t *this, bool commit)
383 {
384 this->flags.commit = commit;
385 }
386
387 METHOD(ike_header_t, get_authonly_flag, bool,
388 private_ike_header_t *this)
389 {
390 return this->flags.authonly;
391 }
392
393 METHOD(ike_header_t, set_authonly_flag, void,
394 private_ike_header_t *this, bool authonly)
395 {
396 this->flags.authonly = authonly;
397 }
398
399 METHOD(ike_header_t, get_exchange_type, u_int8_t,
400 private_ike_header_t *this)
401 {
402 return this->exchange_type;
403 }
404
405 METHOD(ike_header_t, set_exchange_type, void,
406 private_ike_header_t *this, u_int8_t exchange_type)
407 {
408 this->exchange_type = exchange_type;
409 }
410
411 METHOD(ike_header_t, get_message_id, u_int32_t,
412 private_ike_header_t *this)
413 {
414 return this->message_id;
415 }
416
417 METHOD(ike_header_t, set_message_id, void,
418 private_ike_header_t *this, u_int32_t message_id)
419 {
420 this->message_id = message_id;
421 }
422
423 METHOD2(payload_t, ike_header_t, destroy, void,
424 private_ike_header_t *this)
425 {
426 free(this);
427 }
428
429 /*
430 * Described in header.
431 */
432 ike_header_t *ike_header_create()
433 {
434 private_ike_header_t *this;
435
436 INIT(this,
437 .public = {
438 .payload_interface = {
439 .verify = _verify,
440 .get_encoding_rules = _get_encoding_rules,
441 .get_length = _get_length,
442 .get_next_type = _get_next_type,
443 .set_next_type = _set_next_type,
444 .get_type = _get_type,
445 .destroy = _destroy,
446 },
447 .get_initiator_spi = _get_initiator_spi,
448 .set_initiator_spi = _set_initiator_spi,
449 .get_responder_spi = _get_responder_spi,
450 .set_responder_spi = _set_responder_spi,
451 .get_maj_version = _get_maj_version,
452 .set_maj_version = _set_maj_version,
453 .get_min_version = _get_min_version,
454 .set_min_version = _set_min_version,
455 .get_response_flag = _get_response_flag,
456 .set_response_flag = _set_response_flag,
457 .get_version_flag = _get_version_flag,
458 .set_version_flag = _set_version_flag,
459 .get_initiator_flag = _get_initiator_flag,
460 .set_initiator_flag = _set_initiator_flag,
461 .get_encryption_flag = _get_encryption_flag,
462 .set_encryption_flag = _set_encryption_flag,
463 .get_commit_flag = _get_commit_flag,
464 .set_commit_flag = _set_commit_flag,
465 .get_authonly_flag = _get_authonly_flag,
466 .set_authonly_flag = _set_authonly_flag,
467 .get_exchange_type = _get_exchange_type,
468 .set_exchange_type = _set_exchange_type,
469 .get_message_id = _get_message_id,
470 .set_message_id = _set_message_id,
471 .destroy = _destroy,
472 },
473 .length = IKE_HEADER_LENGTH,
474 .exchange_type = EXCHANGE_TYPE_UNDEFINED,
475 );
476
477 return &this->public;
478 }
479
480 /*
481 * Described in header.
482 */
483 ike_header_t *ike_header_create_version(int major, int minor)
484 {
485 ike_header_t *this = ike_header_create();
486
487 this->set_maj_version(this, major);
488 this->set_min_version(this, minor);
489 if (major == IKEV2_MAJOR_VERSION)
490 {
491 this->set_initiator_flag(this, TRUE);
492 }
493 return this;
494 }
495