mediation connections should now properly rekey
[strongswan.git] / src / charon / encoding / generator.c
1 /*
2 * Copyright (C) 2005-2006 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 * $Id$
17 */
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <arpa/inet.h>
22 #include <stdio.h>
23
24
25 #include "generator.h"
26
27 #include <library.h>
28 #include <daemon.h>
29 #include <utils/linked_list.h>
30 #include <encoding/payloads/payload.h>
31 #include <encoding/payloads/proposal_substructure.h>
32 #include <encoding/payloads/transform_substructure.h>
33 #include <encoding/payloads/sa_payload.h>
34 #include <encoding/payloads/ke_payload.h>
35 #include <encoding/payloads/notify_payload.h>
36 #include <encoding/payloads/nonce_payload.h>
37 #include <encoding/payloads/id_payload.h>
38 #include <encoding/payloads/auth_payload.h>
39 #include <encoding/payloads/cert_payload.h>
40 #include <encoding/payloads/certreq_payload.h>
41 #include <encoding/payloads/ts_payload.h>
42 #include <encoding/payloads/delete_payload.h>
43 #include <encoding/payloads/vendor_id_payload.h>
44 #include <encoding/payloads/cp_payload.h>
45 #include <encoding/payloads/configuration_attribute.h>
46 #include <encoding/payloads/eap_payload.h>
47
48
49 typedef struct private_generator_t private_generator_t;
50
51 /**
52 * Private part of a generator_t object.
53 */
54 struct private_generator_t {
55 /**
56 * Public part of a generator_t object.
57 */
58 generator_t public;
59
60 /**
61 * Generates a U_INT-Field type and writes it to buffer.
62 *
63 * @param this private_generator_t object
64 * @param int_type type of U_INT field (U_INT_4, U_INT_8, etc.)
65 * ATTRIBUTE_TYPE is also generated in this function
66 * @param offset offset of value in data struct
67 * @param generator_contexts generator_contexts_t object where the context is written or read from
68 * @return
69 * - SUCCESS
70 * - FAILED if allignment is wrong
71 */
72 void (*generate_u_int_type) (private_generator_t *this,encoding_type_t int_type,u_int32_t offset);
73
74 /**
75 * Get size of current buffer in bytes.
76 *
77 * @param this private_generator_t object
78 * @return Size of buffer in bytes
79 */
80 size_t (*get_current_buffer_size) (private_generator_t *this);
81
82 /**
83 * Get free space of current buffer in bytes.
84 *
85 * @param this private_generator_t object
86 * @return space in buffer in bytes
87 */
88 size_t (*get_current_buffer_space) (private_generator_t *this);
89
90 /**
91 * Get length of data in buffer (in bytes).
92 *
93 * @param this private_generator_t object
94 * @return length of data in bytes
95 */
96 size_t (*get_current_data_length) (private_generator_t *this);
97
98 /**
99 * Get current offset in buffer (in bytes).
100 *
101 * @param this private_generator_t object
102 * @return offset in bytes
103 */
104 u_int32_t (*get_current_buffer_offset) (private_generator_t *this);
105
106 /**
107 * Generates a RESERVED BIT field or a RESERVED BYTE field and writes
108 * it to the buffer.
109 *
110 * @param this private_generator_t object
111 * @param generator_contexts generator_contexts_t object where the context is written or read from
112 * @param bits number of bits to generate
113 */
114 void (*generate_reserved_field) (private_generator_t *this,int bits);
115
116 /**
117 * Generates a FLAG field.
118 *
119 * @param this private_generator_t object
120 * @param generator_contexts generator_contexts_t object where the context is written or read from
121 * @param offset offset of flag value in data struct
122 */
123 void (*generate_flag) (private_generator_t *this,u_int32_t offset);
124
125 /**
126 * Writes the current buffer content into a chunk_t.
127 *
128 * Memory of specific chunk_t gets allocated.
129 *
130 * @param this calling private_generator_t object
131 * @param data pointer of chunk_t to write to
132 */
133 void (*write_chunk) (private_generator_t *this,chunk_t *data);
134
135 /**
136 * Generates a bytestream from a chunk_t.
137 *
138 * @param this private_generator_t object
139 * @param offset offset of chunk_t value in data struct
140 */
141 void (*generate_from_chunk) (private_generator_t *this,u_int32_t offset);
142
143 /**
144 * Makes sure enough space is available in buffer to store amount of bits.
145 *
146 * If buffer is to small to hold the specific amount of bits it
147 * is increased using reallocation function of allocator.
148 *
149 * @param this calling private_generator_t object
150 * @param bits number of bits to make available in buffer
151 */
152 void (*make_space_available) (private_generator_t *this,size_t bits);
153
154 /**
155 * Writes a specific amount of byte into the buffer.
156 *
157 * If buffer is to small to hold the specific amount of bytes it
158 * is increased.
159 *
160 * @param this calling private_generator_t object
161 * @param bytes pointer to bytes to write
162 * @param number_of_bytes number of bytes to write into buffer
163 */
164 void (*write_bytes_to_buffer) (private_generator_t *this,void * bytes,size_t number_of_bytes);
165
166
167 /**
168 * Writes a specific amount of byte into the buffer at a specific offset.
169 *
170 * @warning buffer size is not check to hold the data if offset is to large.
171 *
172 * @param this calling private_generator_t object
173 * @param bytes pointer to bytes to write
174 * @param number_of_bytes number of bytes to write into buffer
175 * @param offset offset to write the data into
176 */
177 void (*write_bytes_to_buffer_at_offset) (private_generator_t *this,void * bytes,size_t number_of_bytes,u_int32_t offset);
178
179 /**
180 * Buffer used to generate the data into.
181 */
182 u_int8_t *buffer;
183
184 /**
185 * Current write position in buffer (one byte aligned).
186 */
187 u_int8_t *out_position;
188
189 /**
190 * Position of last byte in buffer.
191 */
192 u_int8_t *roof_position;
193
194 /**
195 * Current bit writing to in current byte (between 0 and 7).
196 */
197 size_t current_bit;
198
199 /**
200 * Associated data struct to read informations from.
201 */
202 void * data_struct;
203
204 /*
205 * Last payload length position offset in the buffer.
206 */
207 u_int32_t last_payload_length_position_offset;
208
209 /**
210 * Offset of the header length field in the buffer.
211 */
212 u_int32_t header_length_position_offset;
213
214 /**
215 * Last SPI size.
216 */
217 u_int8_t last_spi_size;
218
219 /**
220 * Attribute format of the last generated transform attribute.
221 *
222 * Used to check if a variable value field is used or not for
223 * the transform attribute value.
224 */
225 bool attribute_format;
226
227 /**
228 * Depending on the value of attribute_format this field is used
229 * to hold the length of the transform attribute in bytes.
230 */
231 u_int16_t attribute_length;
232 };
233
234 /**
235 * Implementation of private_generator_t.get_current_buffer_size.
236 */
237 static size_t get_current_buffer_size (private_generator_t *this)
238 {
239 return ((this->roof_position) - (this->buffer));
240 }
241
242 /**
243 * Implementation of private_generator_t.get_current_buffer_space.
244 */
245 static size_t get_current_buffer_space (private_generator_t *this)
246 {
247 /* we know, one byte more */
248 size_t space = (this->roof_position) - (this->out_position);
249 return (space);
250 }
251
252 /**
253 * Implementation of private_generator_t.get_current_data_length.
254 */
255 static size_t get_current_data_length (private_generator_t *this)
256 {
257 return (this->out_position - this->buffer);
258 }
259
260 /**
261 * Implementation of private_generator_t.get_current_buffer_offset.
262 */
263 static u_int32_t get_current_buffer_offset (private_generator_t *this)
264 {
265 return (this->out_position - this->buffer);
266 }
267
268 /**
269 * Implementation of private_generator_t.generate_u_int_type.
270 */
271 static void generate_u_int_type (private_generator_t *this,encoding_type_t int_type,u_int32_t offset)
272 {
273 size_t number_of_bits = 0;
274
275 /* find out number of bits of each U_INT type to check for enough space
276 in buffer */
277 switch (int_type)
278 {
279 case U_INT_4:
280 number_of_bits = 4;
281 break;
282 case TS_TYPE:
283 case U_INT_8:
284 number_of_bits = 8;
285 break;
286 case U_INT_16:
287 case CONFIGURATION_ATTRIBUTE_LENGTH:
288 number_of_bits = 16;
289 break;
290 case U_INT_32:
291 number_of_bits = 32;
292 break;
293 case U_INT_64:
294 number_of_bits = 64;
295 break;
296 case ATTRIBUTE_TYPE:
297 number_of_bits = 15;
298 break;
299 case IKE_SPI:
300 number_of_bits = 64;
301 break;
302
303 default:
304 DBG1(DBG_ENC, "U_INT Type %N is not supported",
305 encoding_type_names, int_type);
306
307 return;
308 }
309 /* U_INT Types of multiple then 8 bits must be aligned */
310 if (((number_of_bits % 8) == 0) && (this->current_bit != 0))
311 {
312 DBG1(DBG_ENC, "U_INT Type %N is not 8 Bit aligned",
313 encoding_type_names, int_type);
314 /* current bit has to be zero for values multiple of 8 bits */
315 return;
316 }
317
318 /* make sure enough space is available in buffer */
319 this->make_space_available(this,number_of_bits);
320 /* now handle each u int type differently */
321 switch (int_type)
322 {
323 case U_INT_4:
324 {
325 if (this->current_bit == 0)
326 {
327 /* highval of current byte in buffer has to be set to the new value*/
328 u_int8_t high_val = *((u_int8_t *)(this->data_struct + offset)) << 4;
329 /* lowval in buffer is not changed */
330 u_int8_t low_val = *(this->out_position) & 0x0F;
331 /* highval is set, low_val is not changed */
332 *(this->out_position) = high_val | low_val;
333 DBG3(DBG_ENC, " => %d", *(this->out_position));
334 /* write position is not changed, just bit position is moved */
335 this->current_bit = 4;
336 }
337 else if (this->current_bit == 4)
338 {
339 /* highval in buffer is not changed */
340 u_int high_val = *(this->out_position) & 0xF0;
341 /* lowval of current byte in buffer has to be set to the new value*/
342 u_int low_val = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
343 *(this->out_position) = high_val | low_val;
344 DBG3(DBG_ENC, " => %d", *(this->out_position));
345 this->out_position++;
346 this->current_bit = 0;
347
348 }
349 else
350 {
351 DBG1(DBG_ENC, "U_INT_4 Type is not 4 Bit aligned");
352 /* 4 Bit integers must have a 4 bit alignment */
353 return;
354 };
355 break;
356 }
357 case TS_TYPE:
358 case U_INT_8:
359 {
360 /* 8 bit values are written as they are */
361 *this->out_position = *((u_int8_t *)(this->data_struct + offset));
362 DBG3(DBG_ENC, " => %d", *(this->out_position));
363 this->out_position++;
364 break;
365
366 }
367 case ATTRIBUTE_TYPE:
368 {
369 /* attribute type must not change first bit uf current byte ! */
370 if (this->current_bit != 1)
371 {
372 DBG1(DBG_ENC, "ATTRIBUTE FORMAT flag is not set");
373 /* first bit has to be set! */
374 return;
375 }
376 /* get value of attribute format flag */
377 u_int8_t attribute_format_flag = *(this->out_position) & 0x80;
378 /* get attribute type value as 16 bit integer*/
379 u_int16_t int16_val = *((u_int16_t*)(this->data_struct + offset));
380 /* unset most significant bit */
381 int16_val &= 0x7FFF;
382 if (attribute_format_flag)
383 {
384 int16_val |= 0x8000;
385 }
386 int16_val = htons(int16_val);
387 DBG3(DBG_ENC, " => %d", int16_val);
388 /* write bytes to buffer (set bit is overwritten)*/
389 this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
390 this->current_bit = 0;
391 break;
392
393 }
394 case U_INT_16:
395 case CONFIGURATION_ATTRIBUTE_LENGTH:
396 {
397 u_int16_t int16_val = htons(*((u_int16_t*)(this->data_struct + offset)));
398 DBG3(DBG_ENC, " => %b", (void*)&int16_val, sizeof(int16_val));
399 this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
400 break;
401 }
402 case U_INT_32:
403 {
404 u_int32_t int32_val = htonl(*((u_int32_t*)(this->data_struct + offset)));
405 DBG3(DBG_ENC, " => %b", (void*)&int32_val, sizeof(int32_val));
406 this->write_bytes_to_buffer(this,&int32_val,sizeof(u_int32_t));
407 break;
408 }
409 case U_INT_64:
410 {
411 /* 64 bit integers are written as two 32 bit integers */
412 u_int32_t int32_val_low = htonl(*((u_int32_t*)(this->data_struct + offset)));
413 u_int32_t int32_val_high = htonl(*((u_int32_t*)(this->data_struct + offset) + 1));
414 DBG3(DBG_ENC, " => %b %b",
415 (void*)&int32_val_low, sizeof(int32_val_low),
416 (void*)&int32_val_high, sizeof(int32_val_high));
417 /* TODO add support for big endian machines */
418 this->write_bytes_to_buffer(this,&int32_val_high,sizeof(u_int32_t));
419 this->write_bytes_to_buffer(this,&int32_val_low,sizeof(u_int32_t));
420 break;
421 }
422
423 case IKE_SPI:
424 {
425 /* 64 bit are written as they come :-) */
426 this->write_bytes_to_buffer(this,(this->data_struct + offset),sizeof(u_int64_t));
427 DBG3(DBG_ENC, " => %b", (void*)(this->data_struct + offset), sizeof(u_int64_t));
428 break;
429 }
430 default:
431 {
432 DBG1(DBG_ENC, "U_INT Type %N is not supported",
433 encoding_type_names, int_type);
434 return;
435 }
436 }
437 }
438
439 /**
440 * Implementation of private_generator_t.generate_reserved_field.
441 */
442 static void generate_reserved_field(private_generator_t *this,int bits)
443 {
444 /* only one bit or 8 bit fields are supported */
445 if ((bits != 1) && (bits != 8))
446 {
447 DBG1(DBG_ENC, "reserved field of %d bits cannot be generated", bits);
448 return ;
449 }
450 /* make sure enough space is available in buffer */
451 this->make_space_available(this,bits);
452
453 if (bits == 1)
454 {
455 /* one bit processing */
456 u_int8_t reserved_bit = ~(1 << (7 - this->current_bit));
457 *(this->out_position) = *(this->out_position) & reserved_bit;
458 if (this->current_bit == 0)
459 {
460 /* memory must be zero */
461 *(this->out_position) = 0x00;
462 }
463
464
465 this->current_bit++;
466 if (this->current_bit >= 8)
467 {
468 this->current_bit = this->current_bit % 8;
469 this->out_position++;
470 }
471 }
472 else
473 {
474 /* one byte processing*/
475 if (this->current_bit > 0)
476 {
477 DBG1(DBG_ENC, "reserved field cannot be written cause "
478 "alignement of current bit is %d", this->current_bit);
479 return;
480 }
481 *(this->out_position) = 0x00;
482 this->out_position++;
483 }
484 }
485
486 /**
487 * Implementation of private_generator_t.generate_flag.
488 */
489 static void generate_flag (private_generator_t *this,u_int32_t offset)
490 {
491 /* value of current flag */
492 u_int8_t flag_value;
493 /* position of flag in current byte */
494 u_int8_t flag;
495
496 /* if the value in the data_struct is TRUE, flag_value is set to 1, 0 otherwise */
497 flag_value = (*((bool *) (this->data_struct + offset))) ? 1 : 0;
498 /* get flag position */
499 flag = (flag_value << (7 - this->current_bit));
500
501 /* make sure one bit is available in buffer */
502 this->make_space_available(this,1);
503 if (this->current_bit == 0)
504 {
505 /* memory must be zero */
506 *(this->out_position) = 0x00;
507 }
508
509 *(this->out_position) = *(this->out_position) | flag;
510
511
512 DBG3(DBG_ENC, " => %d", *(this->out_position));
513
514 this->current_bit++;
515 if (this->current_bit >= 8)
516 {
517 this->current_bit = this->current_bit % 8;
518 this->out_position++;
519 }
520 }
521
522 /**
523 * Implementation of private_generator_t.generate_from_chunk.
524 */
525 static void generate_from_chunk (private_generator_t *this,u_int32_t offset)
526 {
527 if (this->current_bit != 0)
528 {
529 DBG1(DBG_ENC, "can not generate a chunk at Bitpos %d", this->current_bit);
530 return ;
531 }
532
533 /* position in buffer */
534 chunk_t *attribute_value = (chunk_t *)(this->data_struct + offset);
535
536 DBG3(DBG_ENC, " => %B", attribute_value);
537
538 /* use write_bytes_to_buffer function to do the job */
539 this->write_bytes_to_buffer(this,attribute_value->ptr,attribute_value->len);
540 }
541
542 /**
543 * Implementation of private_generator_t.make_space_available.
544 */
545 static void make_space_available (private_generator_t *this, size_t bits)
546 {
547 while (((this->get_current_buffer_space(this) * 8) - this->current_bit) < bits)
548 {
549 /* must increase buffer */
550 size_t old_buffer_size = this->get_current_buffer_size(this);
551 size_t new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
552 size_t out_position_offset = ((this->out_position) - (this->buffer));
553
554 DBG2(DBG_ENC, "increased gen buffer from %d to %d byte",
555 old_buffer_size, new_buffer_size);
556
557 /* Reallocate space for new buffer */
558 this->buffer = realloc(this->buffer,new_buffer_size);
559
560 this->out_position = (this->buffer + out_position_offset);
561 this->roof_position = (this->buffer + new_buffer_size);
562 }
563 }
564
565 /**
566 * Implementation of private_generator_t.write_bytes_to_buffer.
567 */
568 static void write_bytes_to_buffer (private_generator_t *this,void * bytes, size_t number_of_bytes)
569 {
570 int i;
571 u_int8_t *read_position = (u_int8_t *) bytes;
572
573 this->make_space_available(this,number_of_bytes * 8);
574
575 for (i = 0; i < number_of_bytes; i++)
576 {
577 *(this->out_position) = *(read_position);
578 read_position++;
579 this->out_position++;
580 }
581 }
582
583 /**
584 * Implementation of private_generator_t.write_bytes_to_buffer_at_offset.
585 */
586 static void write_bytes_to_buffer_at_offset (private_generator_t *this,void * bytes,size_t number_of_bytes,u_int32_t offset)
587 {
588 int i;
589 u_int8_t *read_position = (u_int8_t *) bytes;
590 u_int8_t *write_position;
591 u_int32_t free_space_after_offset = (this->get_current_buffer_size(this) - offset);
592
593 /* check first if enough space for new data is available */
594 if (number_of_bytes > free_space_after_offset)
595 {
596 this->make_space_available(this,(number_of_bytes - free_space_after_offset) * 8);
597 }
598
599 write_position = this->buffer + offset;
600 for (i = 0; i < number_of_bytes; i++)
601 {
602 *(write_position) = *(read_position);
603 read_position++;
604 write_position++;
605 }
606 }
607
608 /**
609 * Implementation of private_generator_t.write_to_chunk.
610 */
611 static void write_to_chunk (private_generator_t *this,chunk_t *data)
612 {
613 size_t data_length = this->get_current_data_length(this);
614 u_int32_t header_length_field = data_length;
615
616 /* write length into header length field */
617 if (this->header_length_position_offset > 0)
618 {
619 u_int32_t int32_val = htonl(header_length_field);
620 this->write_bytes_to_buffer_at_offset(this,&int32_val,sizeof(u_int32_t),this->header_length_position_offset);
621 }
622
623 if (this->current_bit > 0)
624 data_length++;
625 data->ptr = malloc(data_length);
626 memcpy(data->ptr,this->buffer,data_length);
627 data->len = data_length;
628
629 DBG3(DBG_ENC, "generated data of this generator %B", data);
630 }
631
632 /**
633 * Implementation of private_generator_t.generate_payload.
634 */
635 static void generate_payload (private_generator_t *this,payload_t *payload)
636 {
637 int i;
638 this->data_struct = payload;
639 size_t rule_count;
640 encoding_rule_t *rules;
641 payload_type_t payload_type;
642 u_int8_t *payload_start;
643
644 /* get payload type */
645 payload_type = payload->get_type(payload);
646 /* spi size has to get reseted */
647 this->last_spi_size = 0;
648
649 payload_start = this->out_position;
650
651 DBG2(DBG_ENC, "generating payload of type %N",
652 payload_type_names, payload_type);
653
654 /* each payload has its own encoding rules */
655 payload->get_encoding_rules(payload,&rules,&rule_count);
656
657 for (i = 0; i < rule_count;i++)
658 {
659 DBG2(DBG_ENC, " generating rule %d %N",
660 i, encoding_type_names, rules[i].type);
661 switch (rules[i].type)
662 {
663 /* all u int values, IKE_SPI,TS_TYPE and ATTRIBUTE_TYPE are generated in generate_u_int_type */
664 case U_INT_4:
665 case U_INT_8:
666 case U_INT_16:
667 case U_INT_32:
668 case U_INT_64:
669 case IKE_SPI:
670 case TS_TYPE:
671 case ATTRIBUTE_TYPE:
672 case CONFIGURATION_ATTRIBUTE_LENGTH:
673 {
674 this->generate_u_int_type(this,rules[i].type,rules[i].offset);
675 break;
676 }
677 case RESERVED_BIT:
678 {
679 this->generate_reserved_field(this,1);
680 break;
681 }
682 case RESERVED_BYTE:
683 {
684 this->generate_reserved_field(this,8);
685 break;
686 }
687 case FLAG:
688 {
689 this->generate_flag(this,rules[i].offset);
690 break;
691 }
692 case PAYLOAD_LENGTH:
693 {
694 /* position of payload lenght field is temporary stored */
695 this->last_payload_length_position_offset = this->get_current_buffer_offset(this);
696 /* payload length is generated like an U_INT_16 */
697 this->generate_u_int_type(this,U_INT_16,rules[i].offset);
698 break;
699 }
700 case HEADER_LENGTH:
701 {
702 /* position of header length field is temporary stored */
703 this->header_length_position_offset = this->get_current_buffer_offset(this);
704 /* header length is generated like an U_INT_32 */
705 this->generate_u_int_type(this,U_INT_32,rules[i].offset);
706 break;
707 }
708 case SPI_SIZE:
709 /* spi size is handled as 8 bit unsigned integer */
710 this->generate_u_int_type(this,U_INT_8,rules[i].offset);
711 /* last spi size is temporary stored */
712 this->last_spi_size = *((u_int8_t *)(this->data_struct + rules[i].offset));
713 break;
714 case ADDRESS:
715 {
716 /* the Address value is generated from chunk */
717 this->generate_from_chunk(this,rules[i].offset);
718 break;
719 }
720 case SPI:
721 {
722 /* the SPI value is generated from chunk */
723 this->generate_from_chunk(this,rules[i].offset);
724 break;
725 }
726 case KEY_EXCHANGE_DATA:
727 case NOTIFICATION_DATA:
728 case NONCE_DATA:
729 case ID_DATA:
730 case AUTH_DATA:
731 case CERT_DATA:
732 case CERTREQ_DATA:
733 case SPIS:
734 case CONFIGURATION_ATTRIBUTE_VALUE:
735 case VID_DATA:
736 case EAP_DATA:
737 {
738 u_int32_t payload_length_position_offset;
739 u_int16_t length_of_payload;
740 u_int16_t header_length = 0;
741 u_int16_t length_in_network_order;
742
743 switch(rules[i].type)
744 {
745 case KEY_EXCHANGE_DATA:
746 header_length = KE_PAYLOAD_HEADER_LENGTH;
747 break;
748 case NOTIFICATION_DATA:
749 header_length = NOTIFY_PAYLOAD_HEADER_LENGTH + this->last_spi_size ;
750 break;
751 case NONCE_DATA:
752 header_length = NONCE_PAYLOAD_HEADER_LENGTH;
753 break;
754 case ID_DATA:
755 header_length = ID_PAYLOAD_HEADER_LENGTH;
756 break;
757 case AUTH_DATA:
758 header_length = AUTH_PAYLOAD_HEADER_LENGTH;
759 break;
760 case CERT_DATA:
761 header_length = CERT_PAYLOAD_HEADER_LENGTH;
762 break;
763 case CERTREQ_DATA:
764 header_length = CERTREQ_PAYLOAD_HEADER_LENGTH;
765 break;
766 case SPIS:
767 header_length = DELETE_PAYLOAD_HEADER_LENGTH;
768 break;
769 case VID_DATA:
770 header_length = VENDOR_ID_PAYLOAD_HEADER_LENGTH;
771 break;
772 case CONFIGURATION_ATTRIBUTE_VALUE:
773 header_length = CONFIGURATION_ATTRIBUTE_HEADER_LENGTH;
774 break;
775 case EAP_DATA:
776 header_length = EAP_PAYLOAD_HEADER_LENGTH;
777 break;
778 default:
779 break;
780 }
781
782 /* the data value is generated from chunk */
783 this->generate_from_chunk(this,rules[i].offset);
784
785 payload_length_position_offset = this->last_payload_length_position_offset;
786
787
788 /* Length of payload is calculated */
789 length_of_payload = header_length + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
790
791 length_in_network_order = htons(length_of_payload);
792 this->write_bytes_to_buffer_at_offset(this,&length_in_network_order,sizeof(u_int16_t),payload_length_position_offset);
793 break;
794 }
795 case PROPOSALS:
796 {
797 /* before iterative generate the transforms, store the current payload length position */
798 u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
799 /* Length of SA_PAYLOAD is calculated */
800 u_int16_t length_of_sa_payload = SA_PAYLOAD_HEADER_LENGTH;
801 u_int16_t int16_val;
802 /* proposals are stored in a linked list and so accessed */
803 linked_list_t *proposals = *((linked_list_t **)(this->data_struct + rules[i].offset));
804 iterator_t *iterator;
805 payload_t *current_proposal;
806
807 /* create forward iterator */
808 iterator = proposals->create_iterator(proposals,TRUE);
809 /* every proposal is processed (iterative call )*/
810 while (iterator->iterate(iterator, (void**)&current_proposal))
811 {
812 u_int32_t before_generate_position_offset;
813 u_int32_t after_generate_position_offset;
814
815 before_generate_position_offset = this->get_current_buffer_offset(this);
816 this->public.generate_payload(&(this->public),current_proposal);
817 after_generate_position_offset = this->get_current_buffer_offset(this);
818
819 /* increase size of transform */
820 length_of_sa_payload += (after_generate_position_offset - before_generate_position_offset);
821 }
822 iterator->destroy(iterator);
823
824 int16_val = htons(length_of_sa_payload);
825 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
826 break;
827 }
828 case TRANSFORMS:
829 {
830 /* before iterative generate the transforms, store the current length position */
831 u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
832 u_int16_t length_of_proposal = PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH + this->last_spi_size;
833 u_int16_t int16_val;
834 linked_list_t *transforms = *((linked_list_t **)(this->data_struct + rules[i].offset));
835 iterator_t *iterator;
836 payload_t *current_transform;
837
838 /* create forward iterator */
839 iterator = transforms->create_iterator(transforms,TRUE);
840 while (iterator->iterate(iterator, (void**)&current_transform))
841 {
842 u_int32_t before_generate_position_offset;
843 u_int32_t after_generate_position_offset;
844
845 before_generate_position_offset = this->get_current_buffer_offset(this);
846 this->public.generate_payload(&(this->public),current_transform);
847 after_generate_position_offset = this->get_current_buffer_offset(this);
848
849 /* increase size of transform */
850 length_of_proposal += (after_generate_position_offset - before_generate_position_offset);
851 }
852
853 iterator->destroy(iterator);
854
855 int16_val = htons(length_of_proposal);
856 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
857
858 break;
859 }
860 case TRANSFORM_ATTRIBUTES:
861 {
862 /* before iterative generate the transform attributes, store the current length position */
863 u_int32_t transform_length_position_offset = this->last_payload_length_position_offset;
864 u_int16_t length_of_transform = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
865 u_int16_t int16_val;
866 linked_list_t *transform_attributes =*((linked_list_t **)(this->data_struct + rules[i].offset));
867 iterator_t *iterator;
868 payload_t *current_attribute;
869
870 /* create forward iterator */
871 iterator = transform_attributes->create_iterator(transform_attributes,TRUE);
872 while (iterator->iterate(iterator, (void**)&current_attribute))
873 {
874 u_int32_t before_generate_position_offset;
875 u_int32_t after_generate_position_offset;
876
877 before_generate_position_offset = this->get_current_buffer_offset(this);
878 this->public.generate_payload(&(this->public),current_attribute);
879 after_generate_position_offset = this->get_current_buffer_offset(this);
880
881 /* increase size of transform */
882 length_of_transform += (after_generate_position_offset - before_generate_position_offset);
883 }
884
885 iterator->destroy(iterator);
886
887 int16_val = htons(length_of_transform);
888 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),transform_length_position_offset);
889
890 break;
891 }
892 case CONFIGURATION_ATTRIBUTES:
893 {
894 /* before iterative generate the configuration attributes, store the current length position */
895 u_int32_t configurations_length_position_offset = this->last_payload_length_position_offset;
896 u_int16_t length_of_configurations = CP_PAYLOAD_HEADER_LENGTH;
897 u_int16_t int16_val;
898 linked_list_t *configuration_attributes =*((linked_list_t **)(this->data_struct + rules[i].offset));
899 iterator_t *iterator;
900 payload_t *current_attribute;
901
902 /* create forward iterator */
903 iterator = configuration_attributes->create_iterator(configuration_attributes,TRUE);
904 while (iterator->iterate(iterator, (void**)&current_attribute))
905 {
906 u_int32_t before_generate_position_offset;
907 u_int32_t after_generate_position_offset;
908
909 before_generate_position_offset = this->get_current_buffer_offset(this);
910 this->public.generate_payload(&(this->public),current_attribute);
911 after_generate_position_offset = this->get_current_buffer_offset(this);
912
913 /* increase size of transform */
914 length_of_configurations += (after_generate_position_offset - before_generate_position_offset);
915 }
916
917 iterator->destroy(iterator);
918
919 int16_val = htons(length_of_configurations);
920 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),configurations_length_position_offset);
921
922 break;
923 }
924 case ATTRIBUTE_FORMAT:
925 {
926 this->generate_flag(this,rules[i].offset);
927 /* Attribute format is a flag which is stored in context*/
928 this->attribute_format = *((bool *) (this->data_struct + rules[i].offset));
929 break;
930 }
931
932 case ATTRIBUTE_LENGTH_OR_VALUE:
933 {
934 if (this->attribute_format == FALSE)
935 {
936 this->generate_u_int_type(this,U_INT_16,rules[i].offset);
937 /* this field hold the length of the attribute */
938 this->attribute_length = *((u_int16_t *)(this->data_struct + rules[i].offset));
939 }
940 else
941 {
942 this->generate_u_int_type(this,U_INT_16,rules[i].offset);
943 }
944 break;
945 }
946 case ATTRIBUTE_VALUE:
947 {
948 if (this->attribute_format == FALSE)
949 {
950 DBG2(DBG_ENC, "attribute value has not fixed size");
951 /* the attribute value is generated */
952 this->generate_from_chunk(this,rules[i].offset);
953 }
954 break;
955 }
956 case TRAFFIC_SELECTORS:
957 {
958 /* before iterative generate the traffic_selectors, store the current payload length position */
959 u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
960 /* Length of SA_PAYLOAD is calculated */
961 u_int16_t length_of_ts_payload = TS_PAYLOAD_HEADER_LENGTH;
962 u_int16_t int16_val;
963 /* traffic selectors are stored in a linked list and so accessed */
964 linked_list_t *traffic_selectors = *((linked_list_t **)(this->data_struct + rules[i].offset));
965 iterator_t *iterator;
966 payload_t *current_traffic_selector_substructure;
967
968 /* create forward iterator */
969 iterator = traffic_selectors->create_iterator(traffic_selectors,TRUE);
970 /* every proposal is processed (iterative call )*/
971 while (iterator->iterate(iterator, (void **)&current_traffic_selector_substructure))
972 {
973 u_int32_t before_generate_position_offset;
974 u_int32_t after_generate_position_offset;
975
976 before_generate_position_offset = this->get_current_buffer_offset(this);
977 this->public.generate_payload(&(this->public),current_traffic_selector_substructure);
978 after_generate_position_offset = this->get_current_buffer_offset(this);
979
980 /* increase size of transform */
981 length_of_ts_payload += (after_generate_position_offset - before_generate_position_offset);
982 }
983 iterator->destroy(iterator);
984
985 int16_val = htons(length_of_ts_payload);
986 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
987 break;
988 }
989
990 case ENCRYPTED_DATA:
991 {
992 this->generate_from_chunk(this, rules[i].offset);
993 break;
994 }
995 default:
996 DBG1(DBG_ENC, "field type %N is not supported",
997 encoding_type_names, rules[i].type);
998 return;
999 }
1000 }
1001 DBG2(DBG_ENC, "generating %N payload finished",
1002 payload_type_names, payload_type);
1003 DBG3(DBG_ENC, "generated data for this payload %b",
1004 payload_start, this->out_position-payload_start);
1005 }
1006
1007 /**
1008 * Implementation of generator_t.destroy.
1009 */
1010 static status_t destroy(private_generator_t *this)
1011 {
1012 free(this->buffer);
1013 free(this);
1014 return SUCCESS;
1015 }
1016
1017 /*
1018 * Described in header
1019 */
1020 generator_t *generator_create()
1021 {
1022 private_generator_t *this;
1023
1024 this = malloc_thing(private_generator_t);
1025
1026 /* initiate public functions */
1027 this->public.generate_payload = (void(*)(generator_t*, payload_t *)) generate_payload;
1028 this->public.destroy = (void(*)(generator_t*)) destroy;
1029 this->public.write_to_chunk = (void (*) (generator_t *,chunk_t *)) write_to_chunk;
1030
1031
1032 /* initiate private functions */
1033 this->get_current_buffer_size = get_current_buffer_size;
1034 this->get_current_buffer_space = get_current_buffer_space;
1035 this->get_current_data_length = get_current_data_length;
1036 this->get_current_buffer_offset = get_current_buffer_offset;
1037 this->generate_u_int_type = generate_u_int_type;
1038 this->generate_reserved_field = generate_reserved_field;
1039 this->generate_flag = generate_flag;
1040 this->generate_from_chunk = generate_from_chunk;
1041 this->make_space_available = make_space_available;
1042 this->write_bytes_to_buffer = write_bytes_to_buffer;
1043 this->write_bytes_to_buffer_at_offset = write_bytes_to_buffer_at_offset;
1044
1045
1046 /* allocate memory for buffer */
1047 this->buffer = malloc(GENERATOR_DATA_BUFFER_SIZE);
1048
1049 /* initiate private variables */
1050 this->out_position = this->buffer;
1051 this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE;
1052 this->data_struct = NULL;
1053 this->current_bit = 0;
1054 this->last_payload_length_position_offset = 0;
1055 this->header_length_position_offset = 0;
1056
1057 return &(this->public);
1058 }