ike: Rename encryption_payload to encrypted_payload
[strongswan.git] / src / libcharon / encoding / generator.c
1 /*
2 * Copyright (C) 2011 Tobias Brunner
3 * Copyright (C) 2005-2009 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 #include <stdlib.h>
19 #include <string.h>
20 #include <stdio.h>
21
22 #include "generator.h"
23
24 #include <library.h>
25 #include <daemon.h>
26 #include <collections/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 * TRUE, if debug messages should be logged during generation.
114 */
115 bool debug;
116 };
117
118 /**
119 * Get size of current buffer in bytes.
120 */
121 static int get_size(private_generator_t *this)
122 {
123 return this->roof_position - this->buffer;
124 }
125
126 /**
127 * Get free space of current buffer in bytes.
128 */
129 static int get_space(private_generator_t *this)
130 {
131 return this->roof_position - this->out_position;
132 }
133
134 /**
135 * Get length of data in buffer (in bytes).
136 */
137 static int get_length(private_generator_t *this)
138 {
139 return this->out_position - this->buffer;
140 }
141
142 /**
143 * Get current offset in buffer (in bytes).
144 */
145 static u_int32_t get_offset(private_generator_t *this)
146 {
147 return this->out_position - this->buffer;
148 }
149
150 /**
151 * Makes sure enough space is available in buffer to store amount of bits.
152 */
153 static void make_space_available(private_generator_t *this, int bits)
154 {
155 while ((get_space(this) * 8 - this->current_bit) < bits)
156 {
157 int old_buffer_size, new_buffer_size, out_position_offset;
158
159 old_buffer_size = get_size(this);
160 new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
161 out_position_offset = this->out_position - this->buffer;
162
163 if (this->debug)
164 {
165 DBG2(DBG_ENC, "increasing gen buffer from %d to %d byte",
166 old_buffer_size, new_buffer_size);
167 }
168
169 this->buffer = realloc(this->buffer,new_buffer_size);
170 this->out_position = (this->buffer + out_position_offset);
171 this->roof_position = (this->buffer + new_buffer_size);
172 }
173 }
174
175 /**
176 * Writes a specific amount of byte into the buffer.
177 */
178 static void write_bytes_to_buffer(private_generator_t *this, void *bytes,
179 int number_of_bytes)
180 {
181 int i;
182 u_int8_t *read_position = (u_int8_t *)bytes;
183
184 make_space_available(this, number_of_bytes * 8);
185
186 for (i = 0; i < number_of_bytes; i++)
187 {
188 *(this->out_position) = *(read_position);
189 read_position++;
190 this->out_position++;
191 }
192 }
193
194 /**
195 * Generates a U_INT-Field type and writes it to buffer.
196 */
197 static void generate_u_int_type(private_generator_t *this,
198 encoding_type_t int_type,u_int32_t offset)
199 {
200 int number_of_bits = 0;
201
202 /* find out number of bits of each U_INT type to check for enough space */
203 switch (int_type)
204 {
205 case U_INT_4:
206 number_of_bits = 4;
207 break;
208 case TS_TYPE:
209 case RESERVED_BYTE:
210 case SPI_SIZE:
211 case U_INT_8:
212 number_of_bits = 8;
213 break;
214 case U_INT_16:
215 case PAYLOAD_LENGTH:
216 case ATTRIBUTE_LENGTH:
217 number_of_bits = 16;
218 break;
219 case U_INT_32:
220 number_of_bits = 32;
221 break;
222 case ATTRIBUTE_TYPE:
223 number_of_bits = 15;
224 break;
225 case IKE_SPI:
226 number_of_bits = 64;
227 break;
228 default:
229 DBG1(DBG_ENC, "U_INT Type %N is not supported",
230 encoding_type_names, int_type);
231 return;
232 }
233 if ((number_of_bits % 8) == 0 && this->current_bit != 0)
234 {
235 DBG1(DBG_ENC, "U_INT Type %N is not 8 Bit aligned",
236 encoding_type_names, int_type);
237 return;
238 }
239
240 make_space_available(this, number_of_bits);
241 switch (int_type)
242 {
243 case U_INT_4:
244 {
245 u_int8_t high, low;
246
247 if (this->current_bit == 0)
248 {
249 /* high of current byte in buffer has to be set to the new value*/
250 high = *((u_int8_t *)(this->data_struct + offset)) << 4;
251 /* low in buffer is not changed */
252 low = *(this->out_position) & 0x0F;
253 /* high is set, low_val is not changed */
254 *(this->out_position) = high | low;
255 if (this->debug)
256 {
257 DBG3(DBG_ENC, " => %d", *(this->out_position));
258 }
259 /* write position is not changed, just bit position is moved */
260 this->current_bit = 4;
261 }
262 else if (this->current_bit == 4)
263 {
264 /* high in buffer is not changed */
265 high = *(this->out_position) & 0xF0;
266 /* low of current byte in buffer has to be set to the new value*/
267 low = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
268 *(this->out_position) = high | low;
269 if (this->debug)
270 {
271 DBG3(DBG_ENC, " => %d", *(this->out_position));
272 }
273 this->out_position++;
274 this->current_bit = 0;
275 }
276 else
277 {
278 DBG1(DBG_ENC, "U_INT_4 Type is not 4 Bit aligned");
279 /* 4 Bit integers must have a 4 bit alignment */
280 return;
281 }
282 break;
283 }
284 case TS_TYPE:
285 case RESERVED_BYTE:
286 case SPI_SIZE:
287 case U_INT_8:
288 {
289 /* 8 bit values are written as they are */
290 *this->out_position = *((u_int8_t *)(this->data_struct + offset));
291 if (this->debug)
292 {
293 DBG3(DBG_ENC, " => %d", *(this->out_position));
294 }
295 this->out_position++;
296 break;
297 }
298 case ATTRIBUTE_TYPE:
299 {
300 u_int8_t attribute_format_flag;
301 u_int16_t val;
302
303 /* attribute type must not change first bit of current byte */
304 if (this->current_bit != 1)
305 {
306 DBG1(DBG_ENC, "ATTRIBUTE FORMAT flag is not set");
307 return;
308 }
309 attribute_format_flag = *(this->out_position) & 0x80;
310 /* get attribute type value as 16 bit integer*/
311 val = *((u_int16_t*)(this->data_struct + offset));
312 /* unset most significant bit */
313 val &= 0x7FFF;
314 if (attribute_format_flag)
315 {
316 val |= 0x8000;
317 }
318 val = htons(val);
319 if (this->debug)
320 {
321 DBG3(DBG_ENC, " => %d", val);
322 }
323 /* write bytes to buffer (set bit is overwritten) */
324 write_bytes_to_buffer(this, &val, sizeof(u_int16_t));
325 this->current_bit = 0;
326 break;
327
328 }
329 case U_INT_16:
330 case PAYLOAD_LENGTH:
331 case ATTRIBUTE_LENGTH:
332 {
333 u_int16_t val = htons(*((u_int16_t*)(this->data_struct + offset)));
334 if (this->debug)
335 {
336 DBG3(DBG_ENC, " %b", &val, sizeof(u_int16_t));
337 }
338 write_bytes_to_buffer(this, &val, sizeof(u_int16_t));
339 break;
340 }
341 case U_INT_32:
342 {
343 u_int32_t val = htonl(*((u_int32_t*)(this->data_struct + offset)));
344 if (this->debug)
345 {
346 DBG3(DBG_ENC, " %b", &val, sizeof(u_int32_t));
347 }
348 write_bytes_to_buffer(this, &val, sizeof(u_int32_t));
349 break;
350 }
351 case IKE_SPI:
352 {
353 /* 64 bit are written as-is, no host order conversion */
354 write_bytes_to_buffer(this, this->data_struct + offset,
355 sizeof(u_int64_t));
356 if (this->debug)
357 {
358 DBG3(DBG_ENC, " %b", this->data_struct + offset,
359 sizeof(u_int64_t));
360 }
361 break;
362 }
363 default:
364 {
365 DBG1(DBG_ENC, "U_INT Type %N is not supported",
366 encoding_type_names, int_type);
367 return;
368 }
369 }
370 }
371
372 /**
373 * Generate a FLAG filed
374 */
375 static void generate_flag(private_generator_t *this, u_int32_t offset)
376 {
377 u_int8_t flag_value;
378 u_int8_t flag;
379
380 flag_value = (*((bool *) (this->data_struct + offset))) ? 1 : 0;
381 /* get flag position */
382 flag = (flag_value << (7 - this->current_bit));
383
384 /* make sure one bit is available in buffer */
385 make_space_available(this, 1);
386 if (this->current_bit == 0)
387 {
388 /* memory must be zero */
389 *(this->out_position) = 0x00;
390 }
391
392 *(this->out_position) = *(this->out_position) | flag;
393 if (this->debug)
394 {
395 DBG3(DBG_ENC, " => %d", *this->out_position);
396 }
397
398 this->current_bit++;
399 if (this->current_bit >= 8)
400 {
401 this->current_bit = this->current_bit % 8;
402 this->out_position++;
403 }
404 }
405
406 /**
407 * Generates a bytestream from a chunk_t.
408 */
409 static void generate_from_chunk(private_generator_t *this, u_int32_t offset)
410 {
411 chunk_t *value;
412
413 if (this->current_bit != 0)
414 {
415 DBG1(DBG_ENC, "can not generate a chunk at bitpos %d",
416 this->current_bit);
417 return ;
418 }
419
420 value = (chunk_t *)(this->data_struct + offset);
421 if (this->debug)
422 {
423 DBG3(DBG_ENC, " %B", value);
424 }
425
426 write_bytes_to_buffer(this, value->ptr, value->len);
427 }
428
429 METHOD(generator_t, get_chunk, chunk_t,
430 private_generator_t *this, u_int32_t **lenpos)
431 {
432 chunk_t data;
433
434 *lenpos = (u_int32_t*)(this->buffer + this->header_length_offset);
435 data = chunk_create(this->buffer, get_length(this));
436 if (this->debug)
437 {
438 DBG3(DBG_ENC, "generated data of this generator %B", &data);
439 }
440 return data;
441 }
442
443 METHOD(generator_t, generate_payload, void,
444 private_generator_t *this, payload_t *payload)
445 {
446 int i, offset_start, rule_count;
447 encoding_rule_t *rules;
448 payload_type_t payload_type;
449
450 this->data_struct = payload;
451 payload_type = payload->get_type(payload);
452
453 offset_start = this->out_position - this->buffer;
454
455 if (this->debug)
456 {
457 DBG2(DBG_ENC, "generating payload of type %N",
458 payload_type_names, payload_type);
459 }
460
461 /* each payload has its own encoding rules */
462 rule_count = payload->get_encoding_rules(payload, &rules);
463
464 for (i = 0; i < rule_count;i++)
465 {
466 if (this->debug)
467 {
468 DBG2(DBG_ENC, " generating rule %d %N",
469 i, encoding_type_names, rules[i].type);
470 }
471 switch ((int)rules[i].type)
472 {
473 case U_INT_4:
474 case U_INT_8:
475 case U_INT_16:
476 case U_INT_32:
477 case PAYLOAD_LENGTH:
478 case IKE_SPI:
479 case RESERVED_BYTE:
480 case SPI_SIZE:
481 case TS_TYPE:
482 case ATTRIBUTE_TYPE:
483 case ATTRIBUTE_LENGTH:
484 generate_u_int_type(this, rules[i].type, rules[i].offset);
485 break;
486 case RESERVED_BIT:
487 case FLAG:
488 generate_flag(this, rules[i].offset);
489 break;
490 case HEADER_LENGTH:
491 this->header_length_offset = get_offset(this);
492 generate_u_int_type(this, U_INT_32, rules[i].offset);
493 break;
494 case ADDRESS:
495 case SPI:
496 case CHUNK_DATA:
497 case ENCRYPTED_DATA:
498 generate_from_chunk(this, rules[i].offset);
499 break;
500 case PAYLOAD_LIST + PLV2_PROPOSAL_SUBSTRUCTURE:
501 case PAYLOAD_LIST + PLV1_PROPOSAL_SUBSTRUCTURE:
502 case PAYLOAD_LIST + PLV2_TRANSFORM_SUBSTRUCTURE:
503 case PAYLOAD_LIST + PLV1_TRANSFORM_SUBSTRUCTURE:
504 case PAYLOAD_LIST + PLV2_TRANSFORM_ATTRIBUTE:
505 case PAYLOAD_LIST + PLV1_TRANSFORM_ATTRIBUTE:
506 case PAYLOAD_LIST + PLV2_CONFIGURATION_ATTRIBUTE:
507 case PAYLOAD_LIST + PLV1_CONFIGURATION_ATTRIBUTE:
508 case PAYLOAD_LIST + PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE:
509 {
510 linked_list_t *proposals;
511 enumerator_t *enumerator;
512 payload_t *proposal;
513
514 proposals = *((linked_list_t **)
515 (this->data_struct + rules[i].offset));
516 enumerator = proposals->create_enumerator(proposals);
517 while (enumerator->enumerate(enumerator, &proposal))
518 {
519 generate_payload(this, proposal);
520 }
521 enumerator->destroy(enumerator);
522 break;
523 }
524 case ATTRIBUTE_FORMAT:
525 generate_flag(this, rules[i].offset);
526 /* Attribute format is a flag which is stored in context*/
527 this->attribute_format =
528 *((bool *)(this->data_struct + rules[i].offset));
529 break;
530 case ATTRIBUTE_LENGTH_OR_VALUE:
531 if (this->attribute_format)
532 {
533 generate_u_int_type(this, U_INT_16, rules[i].offset);
534 }
535 else
536 {
537 generate_u_int_type(this, U_INT_16, rules[i].offset);
538 /* this field hold the length of the attribute */
539 this->attribute_length =
540 *((u_int16_t *)(this->data_struct + rules[i].offset));
541 }
542 break;
543 case ATTRIBUTE_VALUE:
544 {
545 if (!this->attribute_format)
546 {
547 if (this->debug)
548 {
549 DBG2(DBG_ENC, "attribute value has not fixed size");
550 }
551 /* the attribute value is generated */
552 generate_from_chunk(this, rules[i].offset);
553 }
554 break;
555 }
556 default:
557 DBG1(DBG_ENC, "field type %N is not supported",
558 encoding_type_names, rules[i].type);
559 return;
560 }
561 }
562 if (this->debug)
563 {
564 DBG2(DBG_ENC, "generating %N payload finished",
565 payload_type_names, payload_type);
566 DBG3(DBG_ENC, "generated data for this payload %b",
567 this->buffer + offset_start,
568 (u_int)(this->out_position - this->buffer - offset_start));
569 }
570 }
571
572 METHOD(generator_t, destroy, void,
573 private_generator_t *this)
574 {
575 free(this->buffer);
576 free(this);
577 }
578
579 /*
580 * Described in header
581 */
582 generator_t *generator_create()
583 {
584 private_generator_t *this;
585
586 INIT(this,
587 .public = {
588 .get_chunk = _get_chunk,
589 .generate_payload = _generate_payload,
590 .destroy = _destroy,
591 },
592 .buffer = malloc(GENERATOR_DATA_BUFFER_SIZE),
593 .debug = TRUE,
594 );
595
596 this->out_position = this->buffer;
597 this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE;
598
599 return &this->public;
600 }
601
602 /*
603 * Described in header
604 */
605 generator_t *generator_create_no_dbg()
606 {
607 private_generator_t *this = (private_generator_t*)generator_create();
608
609 this->debug = FALSE;
610
611 return &this->public;
612 }