Use modified encryption payload to encrypt/decrypt complete IKEv1 messages.
[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, rule_count;
408 encoding_rule_t *rules;
409 payload_type_t payload_type;
410
411 this->data_struct = payload;
412 payload_type = payload->get_type(payload);
413
414 offset_start = this->out_position - this->buffer;
415
416 DBG2(DBG_ENC, "generating payload of type %N",
417 payload_type_names, payload_type);
418
419 /* each payload has its own encoding rules */
420 rule_count = payload->get_encoding_rules(payload, &rules);
421
422 for (i = 0; i < rule_count;i++)
423 {
424 DBG2(DBG_ENC, " generating rule %d %N",
425 i, encoding_type_names, rules[i].type);
426 switch ((int)rules[i].type)
427 {
428 case U_INT_4:
429 case U_INT_8:
430 case U_INT_16:
431 case U_INT_32:
432 case PAYLOAD_LENGTH:
433 case IKE_SPI:
434 case RESERVED_BYTE:
435 case SPI_SIZE:
436 case TS_TYPE:
437 case ATTRIBUTE_TYPE:
438 case CONFIGURATION_ATTRIBUTE_LENGTH:
439 generate_u_int_type(this, rules[i].type, rules[i].offset);
440 break;
441 case RESERVED_BIT:
442 case FLAG:
443 generate_flag(this, rules[i].offset);
444 break;
445 case HEADER_LENGTH:
446 this->header_length_offset = get_offset(this);
447 generate_u_int_type(this, U_INT_32, rules[i].offset);
448 break;
449 case ADDRESS:
450 case SPI:
451 case CHUNK_DATA:
452 case ENCRYPTED_DATA:
453 generate_from_chunk(this, rules[i].offset);
454 break;
455 case PAYLOAD_LIST + PROPOSAL_SUBSTRUCTURE:
456 case PAYLOAD_LIST + PROPOSAL_SUBSTRUCTURE_V1:
457 case PAYLOAD_LIST + TRANSFORM_SUBSTRUCTURE:
458 case PAYLOAD_LIST + TRANSFORM_SUBSTRUCTURE_V1:
459 case PAYLOAD_LIST + TRANSFORM_ATTRIBUTE:
460 case PAYLOAD_LIST + TRANSFORM_ATTRIBUTE_V1:
461 case PAYLOAD_LIST + CONFIGURATION_ATTRIBUTE:
462 case PAYLOAD_LIST + TRAFFIC_SELECTOR_SUBSTRUCTURE:
463 {
464 linked_list_t *proposals;
465 enumerator_t *enumerator;
466 payload_t *proposal;
467
468 proposals = *((linked_list_t **)
469 (this->data_struct + rules[i].offset));
470 enumerator = proposals->create_enumerator(proposals);
471 while (enumerator->enumerate(enumerator, &proposal))
472 {
473 generate_payload(this, proposal);
474 }
475 enumerator->destroy(enumerator);
476 break;
477 }
478 case ATTRIBUTE_FORMAT:
479 generate_flag(this, rules[i].offset);
480 /* Attribute format is a flag which is stored in context*/
481 this->attribute_format =
482 *((bool *)(this->data_struct + rules[i].offset));
483 break;
484 case ATTRIBUTE_LENGTH_OR_VALUE:
485 if (this->attribute_format)
486 {
487 generate_u_int_type(this, U_INT_16, rules[i].offset);
488 }
489 else
490 {
491 generate_u_int_type(this, U_INT_16, rules[i].offset);
492 /* this field hold the length of the attribute */
493 this->attribute_length =
494 *((u_int16_t *)(this->data_struct + rules[i].offset));
495 }
496 break;
497 case ATTRIBUTE_VALUE:
498 {
499 if (!this->attribute_format)
500 {
501 DBG2(DBG_ENC, "attribute value has not fixed size");
502 /* the attribute value is generated */
503 generate_from_chunk(this, rules[i].offset);
504 }
505 break;
506 }
507 default:
508 DBG1(DBG_ENC, "field type %N is not supported",
509 encoding_type_names, rules[i].type);
510 return;
511 }
512 }
513 DBG2(DBG_ENC, "generating %N payload finished",
514 payload_type_names, payload_type);
515 DBG3(DBG_ENC, "generated data for this payload %b",
516 this->buffer + offset_start,
517 this->out_position - this->buffer - offset_start);
518 }
519
520 METHOD(generator_t, destroy, void,
521 private_generator_t *this)
522 {
523 free(this->buffer);
524 free(this);
525 }
526
527 /*
528 * Described in header
529 */
530 generator_t *generator_create()
531 {
532 private_generator_t *this;
533
534 INIT(this,
535 .public = {
536 .get_chunk = _get_chunk,
537 .generate_payload = _generate_payload,
538 .destroy = _destroy,
539 },
540 .buffer = malloc(GENERATOR_DATA_BUFFER_SIZE),
541 );
542
543 this->out_position = this->buffer;
544 this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE;
545
546 return &this->public;
547 }
548