Added SA payload IKEv1 encoding types to generator
[strongswan.git] / src / libcharon / encoding / generator.c
1 /*
2 * Copyright (C) 2005-2009 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include <arpa/inet.h>
20 #include <stdio.h>
21
22 #include "generator.h"
23
24 #include <library.h>
25 #include <daemon.h>
26 #include <utils/linked_list.h>
27 #include <encoding/payloads/payload.h>
28 #include <encoding/payloads/proposal_substructure.h>
29 #include <encoding/payloads/transform_substructure.h>
30 #include <encoding/payloads/sa_payload.h>
31 #include <encoding/payloads/ke_payload.h>
32 #include <encoding/payloads/notify_payload.h>
33 #include <encoding/payloads/nonce_payload.h>
34 #include <encoding/payloads/id_payload.h>
35 #include <encoding/payloads/auth_payload.h>
36 #include <encoding/payloads/cert_payload.h>
37 #include <encoding/payloads/certreq_payload.h>
38 #include <encoding/payloads/ts_payload.h>
39 #include <encoding/payloads/delete_payload.h>
40 #include <encoding/payloads/vendor_id_payload.h>
41 #include <encoding/payloads/cp_payload.h>
42 #include <encoding/payloads/configuration_attribute.h>
43 #include <encoding/payloads/eap_payload.h>
44 #include <encoding/payloads/unknown_payload.h>
45
46 /**
47 * Generating is done in a data buffer.
48 * This is the start size of this buffer in bytes.
49 */
50 #define GENERATOR_DATA_BUFFER_SIZE 500
51
52 /**
53 * Number of bytes to increase the buffer, if it is too small.
54 */
55 #define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500
56
57 typedef struct private_generator_t private_generator_t;
58
59 /**
60 * Private part of a generator_t object.
61 */
62 struct private_generator_t {
63 /**
64 * Public part of a generator_t object.
65 */
66 generator_t public;
67
68 /**
69 * Buffer used to generate the data into.
70 */
71 u_int8_t *buffer;
72
73 /**
74 * Current write position in buffer (one byte aligned).
75 */
76 u_int8_t *out_position;
77
78 /**
79 * Position of last byte in buffer.
80 */
81 u_int8_t *roof_position;
82
83 /**
84 * Current bit writing to in current byte (between 0 and 7).
85 */
86 u_int8_t current_bit;
87
88 /**
89 * Associated data struct to read informations from.
90 */
91 void *data_struct;
92
93 /**
94 * Offset of the header length field in the buffer.
95 */
96 u_int32_t header_length_offset;
97
98 /**
99 * Attribute format of the last generated transform attribute.
100 *
101 * Used to check if a variable value field is used or not for
102 * the transform attribute value.
103 */
104 bool attribute_format;
105
106 /**
107 * Depending on the value of attribute_format this field is used
108 * to hold the length of the transform attribute in bytes.
109 */
110 u_int16_t attribute_length;
111 };
112
113 /**
114 * Get size of current buffer in bytes.
115 */
116 static int get_size(private_generator_t *this)
117 {
118 return this->roof_position - this->buffer;
119 }
120
121 /**
122 * Get free space of current buffer in bytes.
123 */
124 static int get_space(private_generator_t *this)
125 {
126 return this->roof_position - this->out_position;
127 }
128
129 /**
130 * Get length of data in buffer (in bytes).
131 */
132 static int get_length(private_generator_t *this)
133 {
134 return this->out_position - this->buffer;
135 }
136
137 /**
138 * Get current offset in buffer (in bytes).
139 */
140 static u_int32_t get_offset(private_generator_t *this)
141 {
142 return this->out_position - this->buffer;
143 }
144
145 /**
146 * Makes sure enough space is available in buffer to store amount of bits.
147 */
148 static void make_space_available(private_generator_t *this, int bits)
149 {
150 while ((get_space(this) * 8 - this->current_bit) < bits)
151 {
152 int old_buffer_size, new_buffer_size, out_position_offset;
153
154 old_buffer_size = get_size(this);
155 new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
156 out_position_offset = this->out_position - this->buffer;
157
158 DBG2(DBG_ENC, "increasing gen buffer from %d to %d byte",
159 old_buffer_size, new_buffer_size);
160
161 this->buffer = realloc(this->buffer,new_buffer_size);
162 this->out_position = (this->buffer + out_position_offset);
163 this->roof_position = (this->buffer + new_buffer_size);
164 }
165 }
166
167 /**
168 * Writes a specific amount of byte into the buffer.
169 */
170 static void write_bytes_to_buffer(private_generator_t *this, void *bytes,
171 int number_of_bytes)
172 {
173 int i;
174 u_int8_t *read_position = (u_int8_t *)bytes;
175
176 make_space_available(this, number_of_bytes * 8);
177
178 for (i = 0; i < number_of_bytes; i++)
179 {
180 *(this->out_position) = *(read_position);
181 read_position++;
182 this->out_position++;
183 }
184 }
185
186 /**
187 * Generates a U_INT-Field type and writes it to buffer.
188 */
189 static void generate_u_int_type(private_generator_t *this,
190 encoding_type_t int_type,u_int32_t offset)
191 {
192 int number_of_bits = 0;
193
194 /* find out number of bits of each U_INT type to check for enough space */
195 switch (int_type)
196 {
197 case U_INT_4:
198 number_of_bits = 4;
199 break;
200 case TS_TYPE:
201 case RESERVED_BYTE:
202 case SPI_SIZE:
203 case U_INT_8:
204 number_of_bits = 8;
205 break;
206 case U_INT_16:
207 case PAYLOAD_LENGTH:
208 case CONFIGURATION_ATTRIBUTE_LENGTH:
209 number_of_bits = 16;
210 break;
211 case U_INT_32:
212 number_of_bits = 32;
213 break;
214 case ATTRIBUTE_TYPE:
215 number_of_bits = 15;
216 break;
217 case IKE_SPI:
218 number_of_bits = 64;
219 break;
220 default:
221 DBG1(DBG_ENC, "U_INT Type %N is not supported",
222 encoding_type_names, int_type);
223 return;
224 }
225 if ((number_of_bits % 8) == 0 && this->current_bit != 0)
226 {
227 DBG1(DBG_ENC, "U_INT Type %N is not 8 Bit aligned",
228 encoding_type_names, int_type);
229 return;
230 }
231
232 make_space_available(this, number_of_bits);
233 switch (int_type)
234 {
235 case U_INT_4:
236 {
237 u_int8_t high, low;
238
239 if (this->current_bit == 0)
240 {
241 /* high of current byte in buffer has to be set to the new value*/
242 high = *((u_int8_t *)(this->data_struct + offset)) << 4;
243 /* low in buffer is not changed */
244 low = *(this->out_position) & 0x0F;
245 /* high is set, low_val is not changed */
246 *(this->out_position) = high | low;
247 DBG3(DBG_ENC, " => %d", *(this->out_position));
248 /* write position is not changed, just bit position is moved */
249 this->current_bit = 4;
250 }
251 else if (this->current_bit == 4)
252 {
253 /* high in buffer is not changed */
254 high = *(this->out_position) & 0xF0;
255 /* low of current byte in buffer has to be set to the new value*/
256 low = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
257 *(this->out_position) = high | low;
258 DBG3(DBG_ENC, " => %d", *(this->out_position));
259 this->out_position++;
260 this->current_bit = 0;
261 }
262 else
263 {
264 DBG1(DBG_ENC, "U_INT_4 Type is not 4 Bit aligned");
265 /* 4 Bit integers must have a 4 bit alignment */
266 return;
267 }
268 break;
269 }
270 case TS_TYPE:
271 case RESERVED_BYTE:
272 case SPI_SIZE:
273 case U_INT_8:
274 {
275 /* 8 bit values are written as they are */
276 *this->out_position = *((u_int8_t *)(this->data_struct + offset));
277 DBG3(DBG_ENC, " => %d", *(this->out_position));
278 this->out_position++;
279 break;
280 }
281 case ATTRIBUTE_TYPE:
282 {
283 u_int8_t attribute_format_flag;
284 u_int16_t val;
285
286 /* attribute type must not change first bit of current byte */
287 if (this->current_bit != 1)
288 {
289 DBG1(DBG_ENC, "ATTRIBUTE FORMAT flag is not set");
290 return;
291 }
292 attribute_format_flag = *(this->out_position) & 0x80;
293 /* get attribute type value as 16 bit integer*/
294 val = *((u_int16_t*)(this->data_struct + offset));
295 /* unset most significant bit */
296 val &= 0x7FFF;
297 if (attribute_format_flag)
298 {
299 val |= 0x8000;
300 }
301 val = htons(val);
302 DBG3(DBG_ENC, " => %d", val);
303 /* write bytes to buffer (set bit is overwritten) */
304 write_bytes_to_buffer(this, &val, sizeof(u_int16_t));
305 this->current_bit = 0;
306 break;
307
308 }
309 case U_INT_16:
310 case PAYLOAD_LENGTH:
311 case CONFIGURATION_ATTRIBUTE_LENGTH:
312 {
313 u_int16_t val = htons(*((u_int16_t*)(this->data_struct + offset)));
314 DBG3(DBG_ENC, " => %b", &val, sizeof(u_int16_t));
315 write_bytes_to_buffer(this, &val, sizeof(u_int16_t));
316 break;
317 }
318 case U_INT_32:
319 {
320 u_int32_t val = htonl(*((u_int32_t*)(this->data_struct + offset)));
321 DBG3(DBG_ENC, " => %b", &val, sizeof(u_int32_t));
322 write_bytes_to_buffer(this, &val, sizeof(u_int32_t));
323 break;
324 }
325 case IKE_SPI:
326 {
327 /* 64 bit are written as-is, no host order conversion */
328 write_bytes_to_buffer(this, this->data_struct + offset,
329 sizeof(u_int64_t));
330 DBG3(DBG_ENC, " => %b", this->data_struct + offset,
331 sizeof(u_int64_t));
332 break;
333 }
334 default:
335 {
336 DBG1(DBG_ENC, "U_INT Type %N is not supported",
337 encoding_type_names, int_type);
338 return;
339 }
340 }
341 }
342
343 /**
344 * Generate a FLAG filed
345 */
346 static void generate_flag(private_generator_t *this, u_int32_t offset)
347 {
348 u_int8_t flag_value;
349 u_int8_t flag;
350
351 flag_value = (*((bool *) (this->data_struct + offset))) ? 1 : 0;
352 /* get flag position */
353 flag = (flag_value << (7 - this->current_bit));
354
355 /* make sure one bit is available in buffer */
356 make_space_available(this, 1);
357 if (this->current_bit == 0)
358 {
359 /* memory must be zero */
360 *(this->out_position) = 0x00;
361 }
362
363 *(this->out_position) = *(this->out_position) | flag;
364 DBG3(DBG_ENC, " => %d", *this->out_position);
365
366 this->current_bit++;
367 if (this->current_bit >= 8)
368 {
369 this->current_bit = this->current_bit % 8;
370 this->out_position++;
371 }
372 }
373
374 /**
375 * Generates a bytestream from a chunk_t.
376 */
377 static void generate_from_chunk(private_generator_t *this, u_int32_t offset)
378 {
379 chunk_t *value;
380
381 if (this->current_bit != 0)
382 {
383 DBG1(DBG_ENC, "can not generate a chunk at Bitpos %d", this->current_bit);
384 return ;
385 }
386
387 value = (chunk_t *)(this->data_struct + offset);
388 DBG3(DBG_ENC, " => %B", value);
389
390 write_bytes_to_buffer(this, value->ptr, value->len);
391 }
392
393 METHOD(generator_t, get_chunk, chunk_t,
394 private_generator_t *this, u_int32_t **lenpos)
395 {
396 chunk_t data;
397
398 *lenpos = (u_int32_t*)(this->buffer + this->header_length_offset);
399 data = chunk_create(this->buffer, get_length(this));
400 DBG3(DBG_ENC, "generated data of this generator %B", &data);
401 return data;
402 }
403
404 METHOD(generator_t, generate_payload, void,
405 private_generator_t *this,payload_t *payload)
406 {
407 int i, offset_start;
408 size_t rule_count;
409 encoding_rule_t *rules;
410 payload_type_t payload_type;
411
412 this->data_struct = payload;
413 payload_type = payload->get_type(payload);
414
415 offset_start = this->out_position - this->buffer;
416
417 DBG2(DBG_ENC, "generating payload of type %N",
418 payload_type_names, payload_type);
419
420 /* each payload has its own encoding rules */
421 payload->get_encoding_rules(payload, &rules, &rule_count);
422
423 for (i = 0; i < rule_count;i++)
424 {
425 DBG2(DBG_ENC, " generating rule %d %N",
426 i, encoding_type_names, rules[i].type);
427 switch (rules[i].type)
428 {
429 case U_INT_4:
430 case U_INT_8:
431 case U_INT_16:
432 case U_INT_32:
433 case PAYLOAD_LENGTH:
434 case IKE_SPI:
435 case RESERVED_BYTE:
436 case SPI_SIZE:
437 case TS_TYPE:
438 case ATTRIBUTE_TYPE:
439 case CONFIGURATION_ATTRIBUTE_LENGTH:
440 generate_u_int_type(this, rules[i].type, rules[i].offset);
441 break;
442 case RESERVED_BIT:
443 case FLAG:
444 generate_flag(this, rules[i].offset);
445 break;
446 case HEADER_LENGTH:
447 this->header_length_offset = get_offset(this);
448 generate_u_int_type(this, U_INT_32, rules[i].offset);
449 break;
450 case ADDRESS:
451 case SPI:
452 case KEY_EXCHANGE_DATA:
453 case NOTIFICATION_DATA:
454 case NONCE_DATA:
455 case ID_DATA:
456 case AUTH_DATA:
457 case CERT_DATA:
458 case CERTREQ_DATA:
459 case SPIS:
460 case CONFIGURATION_ATTRIBUTE_VALUE:
461 case VID_DATA:
462 case EAP_DATA:
463 case ENCRYPTED_DATA:
464 case UNKNOWN_DATA:
465 generate_from_chunk(this, rules[i].offset);
466 break;
467 case PROPOSALS:
468 case PROPOSALS_V1:
469 case TRANSFORMS:
470 case TRANSFORMS_V1:
471 case TRANSFORM_ATTRIBUTES:
472 case TRANSFORM_ATTRIBUTES_V1:
473 case CONFIGURATION_ATTRIBUTES:
474 case TRAFFIC_SELECTORS:
475 {
476 linked_list_t *proposals;
477 enumerator_t *enumerator;
478 payload_t *proposal;
479
480 proposals = *((linked_list_t **)
481 (this->data_struct + rules[i].offset));
482 enumerator = proposals->create_enumerator(proposals);
483 while (enumerator->enumerate(enumerator, &proposal))
484 {
485 generate_payload(this, proposal);
486 }
487 enumerator->destroy(enumerator);
488 break;
489 }
490 case ATTRIBUTE_FORMAT:
491 generate_flag(this, rules[i].offset);
492 /* Attribute format is a flag which is stored in context*/
493 this->attribute_format =
494 *((bool *)(this->data_struct + rules[i].offset));
495 break;
496 case ATTRIBUTE_LENGTH_OR_VALUE:
497 if (this->attribute_format)
498 {
499 generate_u_int_type(this, U_INT_16, rules[i].offset);
500 }
501 else
502 {
503 generate_u_int_type(this, U_INT_16, rules[i].offset);
504 /* this field hold the length of the attribute */
505 this->attribute_length =
506 *((u_int16_t *)(this->data_struct + rules[i].offset));
507 }
508 break;
509 case ATTRIBUTE_VALUE:
510 {
511 if (!this->attribute_format)
512 {
513 DBG2(DBG_ENC, "attribute value has not fixed size");
514 /* the attribute value is generated */
515 generate_from_chunk(this, rules[i].offset);
516 }
517 break;
518 }
519 default:
520 DBG1(DBG_ENC, "field type %N is not supported",
521 encoding_type_names, rules[i].type);
522 return;
523 }
524 }
525 DBG2(DBG_ENC, "generating %N payload finished",
526 payload_type_names, payload_type);
527 DBG3(DBG_ENC, "generated data for this payload %b",
528 this->buffer + offset_start,
529 this->out_position - this->buffer - offset_start);
530 }
531
532 METHOD(generator_t, destroy, void,
533 private_generator_t *this)
534 {
535 free(this->buffer);
536 free(this);
537 }
538
539 /*
540 * Described in header
541 */
542 generator_t *generator_create()
543 {
544 private_generator_t *this;
545
546 INIT(this,
547 .public = {
548 .get_chunk = _get_chunk,
549 .generate_payload = _generate_payload,
550 .destroy = _destroy,
551 },
552 .buffer = malloc(GENERATOR_DATA_BUFFER_SIZE),
553 );
554
555 this->out_position = this->buffer;
556 this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE;
557
558 return &this->public;
559 }
560