merged EAP framework from branch into trunk
[strongswan.git] / src / charon / encoding / parser.c
1 /**
2 * @file parser.c
3 *
4 * @brief Implementation of parser_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include <stdlib.h>
25 #include <arpa/inet.h>
26 #include <string.h>
27
28 #include "parser.h"
29
30 #include <library.h>
31 #include <daemon.h>
32 #include <utils/linked_list.h>
33 #include <encoding/payloads/encodings.h>
34 #include <encoding/payloads/payload.h>
35 #include <encoding/payloads/sa_payload.h>
36 #include <encoding/payloads/proposal_substructure.h>
37 #include <encoding/payloads/transform_substructure.h>
38 #include <encoding/payloads/transform_attribute.h>
39 #include <encoding/payloads/ke_payload.h>
40 #include <encoding/payloads/nonce_payload.h>
41 #include <encoding/payloads/id_payload.h>
42 #include <encoding/payloads/notify_payload.h>
43 #include <encoding/payloads/encryption_payload.h>
44 #include <encoding/payloads/auth_payload.h>
45 #include <encoding/payloads/cert_payload.h>
46 #include <encoding/payloads/certreq_payload.h>
47 #include <encoding/payloads/ts_payload.h>
48 #include <encoding/payloads/delete_payload.h>
49 #include <encoding/payloads/vendor_id_payload.h>
50 #include <encoding/payloads/cp_payload.h>
51 #include <encoding/payloads/configuration_attribute.h>
52 #include <encoding/payloads/eap_payload.h>
53 #include <encoding/payloads/unknown_payload.h>
54
55
56 typedef struct private_parser_t private_parser_t;
57
58 /**
59 * Private data stored in a context.
60 *
61 * Contains pointers and counters to store current state.
62 */
63 struct private_parser_t {
64 /**
65 * Public members, see parser_t.
66 */
67 parser_t public;
68
69 /**
70 * @brief Parse a 4-Bit unsigned integer from the current parsing position.
71 *
72 * @param this parser_t object
73 * @param rule_number number of current rule
74 * @param[out] output_pos pointer where to write the parsed result
75 * @return
76 * - SUCCESS or
77 * - PARSE_ERROR when not successful
78 */
79 status_t (*parse_uint4) (private_parser_t *this, int rule_number, u_int8_t *output_pos);
80
81 /**
82 * @brief Parse a 8-Bit unsigned integer from the current parsing position.
83 *
84 * @param this parser_t object
85 * @param rule_number number of current rule
86 * @param[out] output_pos pointer where to write the parsed result
87 * @return
88 * - SUCCESS or
89 * - PARSE_ERROR when not successful
90 */
91 status_t (*parse_uint8) (private_parser_t *this, int rule_number, u_int8_t *output_pos);
92
93 /**
94 * @brief Parse a 15-Bit unsigned integer from the current parsing position.
95 *
96 * This is a special case used for ATTRIBUTE_TYPE.
97 * Big-/Little-endian conversion is done here.
98 *
99 * @param this parser_t object
100 * @param rule_number number of current rule
101 * @param[out] output_pos pointer where to write the parsed result
102 * @return
103 * - SUCCESS or
104 * - PARSE_ERROR when not successful
105 */
106 status_t (*parse_uint15) (private_parser_t *this, int rule_number, u_int16_t *output_pos);
107
108 /**
109 * @brief Parse a 16-Bit unsigned integer from the current parsing position.
110 *
111 * Big-/Little-endian conversion is done here.
112 *
113 * @param this parser_t object
114 * @param rule_number number of current rule
115 * @param[out] output_pos pointer where to write the parsed result
116 * @return
117 * - SUCCESS or
118 * - PARSE_ERROR when not successful
119 */
120 status_t (*parse_uint16) (private_parser_t *this, int rule_number, u_int16_t *output_pos);
121
122 /**
123 * @brief Parse a 32-Bit unsigned integer from the current parsing position.
124 *
125 * Big-/Little-endian conversion is done here.
126 *
127 * @param this parser_t object
128 * @param rule_number number of current rule
129 * @param[out] output_pos pointer where to write the parsed result
130 * @return
131 * - SUCCESS or
132 * - PARSE_ERROR when not successful
133 */
134 status_t (*parse_uint32) (private_parser_t *this, int rule_number, u_int32_t *output_pos);
135
136 /**
137 * @brief Parse a 64-Bit unsigned integer from the current parsing position.
138 *
139 * @todo add support for big-endian machines.
140 *
141 * @param this parser_t object
142 * @param rule_number number of current rule
143 * @param[out] output_pos pointer where to write the parsed result
144 * @return
145 * - SUCCESS or
146 * - PARSE_ERROR when not successful
147 */
148 status_t (*parse_uint64) (private_parser_t *this, int rule_number, u_int64_t *output_pos);
149
150 /**
151 * @brief Parse a given amount of bytes and writes them to a specific location
152 *
153 * @param this parser_t object
154 * @param rule_number number of current rule
155 * @param[out] output_pos pointer where to write the parsed result
156 * @param bytes number of bytes to parse
157 * @return
158 * - SUCCESS or
159 * - PARSE_ERROR when not successful
160 */
161 status_t (*parse_bytes) (private_parser_t *this, int rule_number, u_int8_t *output_pos,size_t bytes);
162
163 /**
164 * @brief Parse a single Bit from the current parsing position
165 *
166 * @param this parser_t object
167 * @param rule_number number of current rule
168 * @param[out] output_pos pointer where to write the parsed result
169 * @return
170 * - SUCCESS or
171 * - PARSE_ERROR when not successful
172 */
173 status_t (*parse_bit) (private_parser_t *this, int rule_number, bool *output_pos);
174
175 /**
176 * @brief Parse substructures in a list
177 *
178 * This function calls the parser recursively to parse contained substructures
179 * in a linked_list_t. The list must already be created. Payload defines
180 * the type of the substructures. parsing is continued until the specified length
181 * is completely parsed.
182 *
183 * @param this parser_t object
184 * @param rule_number number of current rule
185 * @param[out] output_pos pointer of a linked_list where substructures are added
186 * @param payload_type type of the contained substructures to parse
187 * @param length number of bytes to parse in this list
188 * @return
189 * - SUCCESS or
190 * - PARSE_ERROR when not successful
191 */
192 status_t (*parse_list) (private_parser_t *this, int rule_number, linked_list_t **output_pos, payload_type_t payload_ype, size_t length);
193
194 /**
195 * @brief Parse data from current parsing position in a chunk.
196 *
197 * This function clones length number of bytes to output_pos, without
198 * modifiyng them. Space will be allocated and must be freed by caller.
199 *
200 * @param this parser_t object
201 * @param rule_number number of current rule
202 * @param[out] output_pos pointer of a chunk which will point to the allocated data
203 * @param length number of bytes to clone
204 * @return
205 * - SUCCESS or
206 * - PARSE_ERROR when not successful
207 */
208 status_t (*parse_chunk) (private_parser_t *this, int rule_number, chunk_t *output_pos, size_t length);
209
210 /**
211 * Current bit for reading in input data.
212 */
213 u_int8_t bit_pos;
214
215 /**
216 * Current byte for reading in input data.
217 */
218 u_int8_t *byte_pos;
219
220 /**
221 * Input data to parse.
222 */
223 u_int8_t *input;
224
225 /**
226 * Roof of input, used for length-checking.
227 */
228 u_int8_t *input_roof;
229
230 /**
231 * Set of encoding rules for this parsing session.
232 */
233 encoding_rule_t *rules;
234 };
235
236 /**
237 * Implementation of private_parser_t.parse_uint4.
238 */
239 static status_t parse_uint4(private_parser_t *this, int rule_number, u_int8_t *output_pos)
240 {
241 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
242 {
243 DBG1(DBG_ENC, " not enough input to parse rule %d %N",
244 rule_number, encoding_type_names, this->rules[rule_number].type);
245 return PARSE_ERROR;
246 }
247 switch (this->bit_pos)
248 {
249 case 0:
250 /* caller interested in result ? */
251 if (output_pos != NULL)
252 {
253 *output_pos = *(this->byte_pos) >> 4;
254 }
255 this->bit_pos = 4;
256 break;
257 case 4:
258 /* caller interested in result ? */
259 if (output_pos != NULL)
260 {
261 *output_pos = *(this->byte_pos) & 0x0F;
262 }
263 this->bit_pos = 0;
264 this->byte_pos++;
265 break;
266 default:
267 DBG2(DBG_ENC, " found rule %d %N on bitpos %d",
268 rule_number, encoding_type_names,
269 this->rules[rule_number].type, this->bit_pos);
270 return PARSE_ERROR;
271 }
272
273 if (output_pos != NULL)
274 {
275 DBG3(DBG_ENC, " => %d", *output_pos);
276 }
277
278 return SUCCESS;
279 }
280
281 /**
282 * Implementation of private_parser_t.parse_uint8.
283 */
284 static status_t parse_uint8(private_parser_t *this, int rule_number, u_int8_t *output_pos)
285 {
286 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
287 {
288 DBG1(DBG_ENC, " not enough input to parse rule %d %N",
289 rule_number, encoding_type_names, this->rules[rule_number].type);
290 return PARSE_ERROR;
291 }
292 if (this->bit_pos)
293 {
294 DBG1(DBG_ENC, " found rule %d %N on bitpos %d",
295 rule_number, encoding_type_names,
296 this->rules[rule_number].type, this->bit_pos);
297 return PARSE_ERROR;
298 }
299
300 /* caller interested in result ? */
301 if (output_pos != NULL)
302 {
303 *output_pos = *(this->byte_pos);
304 DBG3(DBG_ENC, " => %d", *output_pos);
305 }
306 this->byte_pos++;
307
308 return SUCCESS;
309 }
310
311 /**
312 * Implementation of private_parser_t.parse_uint15.
313 */
314 static status_t parse_uint15(private_parser_t *this, int rule_number, u_int16_t *output_pos)
315 {
316 if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
317 {
318 DBG1(DBG_ENC, " not enough input to parse rule %d %N",
319 rule_number, encoding_type_names, this->rules[rule_number].type);
320 return PARSE_ERROR;
321 }
322 if (this->bit_pos != 1)
323 {
324 DBG2(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
325 encoding_type_names, this->rules[rule_number].type, this->bit_pos);
326 return PARSE_ERROR;
327 }
328 /* caller interested in result ? */
329 if (output_pos != NULL)
330 {
331 *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & ~0x8000;
332 DBG3(DBG_ENC, " => %d", *output_pos);
333 }
334 this->byte_pos += 2;
335 this->bit_pos = 0;
336
337 return SUCCESS;
338 }
339
340 /**
341 * Implementation of private_parser_t.parse_uint16.
342 */
343 static status_t parse_uint16(private_parser_t *this, int rule_number, u_int16_t *output_pos)
344 {
345 if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
346 {
347 DBG1(DBG_ENC, " not enough input to parse rule %d %N",
348 rule_number, encoding_type_names, this->rules[rule_number].type);
349 return PARSE_ERROR;
350 }
351 if (this->bit_pos)
352 {
353 DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
354 encoding_type_names, this->rules[rule_number].type, this->bit_pos);
355 return PARSE_ERROR;
356 }
357 /* caller interested in result ? */
358 if (output_pos != NULL)
359 {
360 *output_pos = ntohs(*((u_int16_t*)this->byte_pos));
361
362 DBG3(DBG_ENC, " => %d", *output_pos);
363 }
364 this->byte_pos += 2;
365
366 return SUCCESS;
367 }
368 /**
369 * Implementation of private_parser_t.parse_uint32.
370 */
371 static status_t parse_uint32(private_parser_t *this, int rule_number, u_int32_t *output_pos)
372 {
373 if (this->byte_pos + sizeof(u_int32_t) > this->input_roof)
374 {
375 DBG1(DBG_ENC, " not enough input to parse rule %d %N",
376 rule_number, encoding_type_names, this->rules[rule_number].type);
377 return PARSE_ERROR;
378 }
379 if (this->bit_pos)
380 {
381 DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
382 encoding_type_names, this->rules[rule_number].type, this->bit_pos);
383 return PARSE_ERROR;
384 }
385 /* caller interested in result ? */
386 if (output_pos != NULL)
387 {
388 *output_pos = ntohl(*((u_int32_t*)this->byte_pos));
389
390 DBG3(DBG_ENC, " => %d", *output_pos);
391 }
392 this->byte_pos += 4;
393
394 return SUCCESS;
395 }
396
397 /**
398 * Implementation of private_parser_t.parse_uint64.
399 */
400 static status_t parse_uint64(private_parser_t *this, int rule_number, u_int64_t *output_pos)
401 {
402 if (this->byte_pos + sizeof(u_int64_t) > this->input_roof)
403 {
404 DBG1(DBG_ENC, " not enough input to parse rule %d %N",
405 rule_number, encoding_type_names, this->rules[rule_number].type);
406 return PARSE_ERROR;
407 }
408 if (this->bit_pos)
409 {
410 DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
411 encoding_type_names, this->rules[rule_number].type, this->bit_pos);
412 return PARSE_ERROR;
413 }
414 /* caller interested in result ? */
415 if (output_pos != NULL)
416 {
417 /* assuming little endian host order */
418 *(output_pos + 1) = ntohl(*((u_int32_t*)this->byte_pos));
419 *output_pos = ntohl(*(((u_int32_t*)this->byte_pos) + 1));
420
421 DBG3(DBG_ENC, " => %b", (void*)output_pos, sizeof(u_int64_t));
422 }
423 this->byte_pos += 8;
424
425 return SUCCESS;
426 }
427
428 /**
429 * Implementation of private_parser_t.parse_bytes.
430 */
431 static status_t parse_bytes (private_parser_t *this, int rule_number, u_int8_t *output_pos,size_t bytes)
432 {
433 if (this->byte_pos + bytes > this->input_roof)
434 {
435 DBG1(DBG_ENC, " not enough input to parse rule %d %N",
436 rule_number, encoding_type_names, this->rules[rule_number].type);
437 return PARSE_ERROR;
438 }
439 if (this->bit_pos)
440 {
441 DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
442 encoding_type_names, this->rules[rule_number].type, this->bit_pos);
443 return PARSE_ERROR;
444 }
445
446 /* caller interested in result ? */
447 if (output_pos != NULL)
448 {
449 memcpy(output_pos,this->byte_pos,bytes);
450
451 DBG3(DBG_ENC, " => %b", (void*)output_pos, bytes);
452 }
453 this->byte_pos += bytes;
454
455 return SUCCESS;
456 }
457
458 /**
459 * Implementation of private_parser_t.parse_bit.
460 */
461 static status_t parse_bit(private_parser_t *this, int rule_number, bool *output_pos)
462 {
463 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
464 {
465 DBG1(DBG_ENC, " not enough input to parse rule %d %N",
466 rule_number, encoding_type_names, this->rules[rule_number].type);
467 return PARSE_ERROR;
468 }
469 /* caller interested in result ? */
470 if (output_pos != NULL)
471 {
472 u_int8_t mask;
473 mask = 0x01 << (7 - this->bit_pos);
474 *output_pos = *this->byte_pos & mask;
475
476 if (*output_pos)
477 {
478 /* set to a "clean", comparable true */
479 *output_pos = TRUE;
480 }
481
482 DBG3(DBG_ENC, " => %d", *output_pos);
483 }
484 this->bit_pos = (this->bit_pos + 1) % 8;
485 if (this->bit_pos == 0)
486 {
487 this->byte_pos++;
488 }
489
490 return SUCCESS;
491 }
492
493 /**
494 * Implementation of private_parser_t.parse_list.
495 */
496 static status_t parse_list(private_parser_t *this, int rule_number, linked_list_t **output_pos, payload_type_t payload_type, size_t length)
497 {
498 linked_list_t * list = *output_pos;
499
500 if (length < 0)
501 {
502 DBG1(DBG_ENC, " invalid length for rule %d %N",
503 rule_number, encoding_type_names, this->rules[rule_number].type);
504 return PARSE_ERROR;
505 }
506
507 if (this->bit_pos)
508 {
509 DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
510 encoding_type_names, this->rules[rule_number].type, this->bit_pos);
511 return PARSE_ERROR;
512 }
513
514 while (length > 0)
515 {
516 u_int8_t *pos_before = this->byte_pos;
517 payload_t *payload;
518 status_t status;
519 DBG2(DBG_ENC, " %d bytes left, parsing recursively %N",
520 length, payload_type_names, payload_type);
521 status = this->public.parse_payload((parser_t*)this, payload_type, &payload);
522 if (status != SUCCESS)
523 {
524 DBG1(DBG_ENC, " parsing of a %N substructure failed",
525 payload_type_names, payload_type);
526 return status;
527 }
528 list->insert_last(list, payload);
529 length -= this->byte_pos - pos_before;
530 }
531 *output_pos = list;
532 return SUCCESS;
533 }
534
535 /**
536 * Implementation of private_parser_t.parse_chunk.
537 */
538 static status_t parse_chunk(private_parser_t *this, int rule_number, chunk_t *output_pos, size_t length)
539 {
540 if (this->byte_pos + length > this->input_roof)
541 {
542 DBG1(DBG_ENC, " not enough input (%d bytes) to parse rule %d %N",
543 length, rule_number, encoding_type_names, this->rules[rule_number].type);
544 return PARSE_ERROR;
545 }
546 if (this->bit_pos)
547 {
548 DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number,
549 encoding_type_names, this->rules[rule_number].type, this->bit_pos);
550 return PARSE_ERROR;
551 }
552 if (output_pos != NULL)
553 {
554 output_pos->len = length;
555 output_pos->ptr = malloc(length);
556 memcpy(output_pos->ptr, this->byte_pos, length);
557 }
558 this->byte_pos += length;
559 DBG3(DBG_ENC, " => %b", (void*)output_pos->ptr, length);
560
561 return SUCCESS;
562 }
563
564 /**
565 * Implementation of parser_t.parse_payload.
566 */
567 static status_t parse_payload(private_parser_t *this, payload_type_t payload_type, payload_t **payload)
568 {
569 payload_t *pld;
570 void *output;
571 size_t rule_count, payload_length = 0, spi_size = 0, attribute_length = 0;
572 u_int16_t ts_type = 0;
573 bool attribute_format = FALSE;
574 int rule_number;
575 encoding_rule_t *rule;
576
577 /* create instance of the payload to parse */
578 pld = payload_create(payload_type);
579
580 DBG2(DBG_ENC, "parsing %N payload, %d bytes left",
581 payload_type_names, payload_type, this->input_roof - this->byte_pos);
582
583 DBG3(DBG_ENC, "parsing payload from %b",
584 this->byte_pos, this->input_roof-this->byte_pos);
585
586 if (pld->get_type(pld) == UNKNOWN_PAYLOAD)
587 {
588 DBG1(DBG_ENC, " payload type %d is unknown, handling as %N",
589 payload_type, payload_type_names, UNKNOWN_PAYLOAD);
590 }
591
592 /* base pointer for output, avoids casting in every rule */
593 output = pld;
594
595 /* parse the payload with its own rulse */
596 pld->get_encoding_rules(pld, &(this->rules), &rule_count);
597 for (rule_number = 0; rule_number < rule_count; rule_number++)
598 {
599 rule = &(this->rules[rule_number]);
600 DBG2(DBG_ENC, " parsing rule %d %N",
601 rule_number, encoding_type_names, rule->type);
602 switch (rule->type)
603 {
604 case U_INT_4:
605 {
606 if (this->parse_uint4(this, rule_number, output + rule->offset) != SUCCESS)
607 {
608 pld->destroy(pld);
609 return PARSE_ERROR;
610 }
611 break;
612 }
613 case U_INT_8:
614 {
615 if (this->parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
616 {
617 pld->destroy(pld);
618 return PARSE_ERROR;
619 }
620 break;
621 }
622 case U_INT_16:
623 {
624 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
625 {
626 pld->destroy(pld);
627 return PARSE_ERROR;
628 }
629 break;
630 }
631 case U_INT_32:
632 {
633 if (this->parse_uint32(this, rule_number, output + rule->offset) != SUCCESS)
634 {
635 pld->destroy(pld);
636 return PARSE_ERROR;
637 }
638 break;
639 }
640 case U_INT_64:
641 {
642 if (this->parse_uint64(this, rule_number, output + rule->offset) != SUCCESS)
643 {
644 pld->destroy(pld);
645 return PARSE_ERROR;
646 }
647 break;
648 }
649 case IKE_SPI:
650 {
651 if (this->parse_bytes(this, rule_number, output + rule->offset,8) != SUCCESS)
652 {
653 pld->destroy(pld);
654 return PARSE_ERROR;
655 }
656 break;
657 }
658 case RESERVED_BIT:
659 {
660 if (this->parse_bit(this, rule_number, NULL) != SUCCESS)
661 {
662 pld->destroy(pld);
663 return PARSE_ERROR;
664 }
665 break;
666 }
667 case RESERVED_BYTE:
668 {
669 if (this->parse_uint8(this, rule_number, NULL) != SUCCESS)
670 {
671 pld->destroy(pld);
672 return PARSE_ERROR;
673 }
674 break;
675 }
676 case FLAG:
677 {
678 if (this->parse_bit(this, rule_number, output + rule->offset) != SUCCESS)
679 {
680 pld->destroy(pld);
681 return PARSE_ERROR;
682 }
683 break;
684 }
685 case PAYLOAD_LENGTH:
686 {
687 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
688 {
689 pld->destroy(pld);
690 return PARSE_ERROR;
691 }
692 payload_length = *(u_int16_t*)(output + rule->offset);
693 break;
694 }
695 case HEADER_LENGTH:
696 {
697 if (this->parse_uint32(this, rule_number, output + rule->offset) != SUCCESS)
698 {
699 pld->destroy(pld);
700 return PARSE_ERROR;
701 }
702 break;
703 }
704 case SPI_SIZE:
705 {
706 if (this->parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
707 {
708 pld->destroy(pld);
709 return PARSE_ERROR;
710 }
711 spi_size = *(u_int8_t*)(output + rule->offset);
712 break;
713 }
714 case SPI:
715 {
716 if (this->parse_chunk(this, rule_number, output + rule->offset, spi_size) != SUCCESS)
717 {
718 pld->destroy(pld);
719 return PARSE_ERROR;
720 }
721 break;
722 }
723 case PROPOSALS:
724 {
725 size_t proposals_length = payload_length - SA_PAYLOAD_HEADER_LENGTH;
726 if (this->parse_list(this, rule_number, output + rule->offset, PROPOSAL_SUBSTRUCTURE, proposals_length) != SUCCESS)
727 {
728 pld->destroy(pld);
729 return PARSE_ERROR;
730 }
731 break;
732 }
733 case TRANSFORMS:
734 {
735 size_t transforms_length = payload_length - spi_size - PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH;
736 if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_SUBSTRUCTURE, transforms_length) != SUCCESS)
737 {
738 pld->destroy(pld);
739 return PARSE_ERROR;
740 }
741 break;
742 }
743 case TRANSFORM_ATTRIBUTES:
744 {
745 size_t transform_a_length = payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
746 if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_ATTRIBUTE, transform_a_length) != SUCCESS)
747 {
748 pld->destroy(pld);
749 return PARSE_ERROR;
750 }
751 break;
752 }
753 case CONFIGURATION_ATTRIBUTES:
754 {
755 size_t configuration_attributes_length = payload_length - CP_PAYLOAD_HEADER_LENGTH;
756 if (this->parse_list(this, rule_number, output + rule->offset, CONFIGURATION_ATTRIBUTE, configuration_attributes_length) != SUCCESS)
757 {
758 pld->destroy(pld);
759 return PARSE_ERROR;
760 }
761 break;
762 }
763 case ATTRIBUTE_FORMAT:
764 {
765 if (this->parse_bit(this, rule_number, output + rule->offset) != SUCCESS)
766 {
767 pld->destroy(pld);
768 return PARSE_ERROR;
769 }
770 attribute_format = *(bool*)(output + rule->offset);
771 break;
772 }
773 case ATTRIBUTE_TYPE:
774 {
775 if (this->parse_uint15(this, rule_number, output + rule->offset) != SUCCESS)
776 {
777 pld->destroy(pld);
778 return PARSE_ERROR;
779 }
780 attribute_format = *(bool*)(output + rule->offset);
781 break;
782 }
783 case CONFIGURATION_ATTRIBUTE_LENGTH:
784 {
785 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
786 {
787 pld->destroy(pld);
788 return PARSE_ERROR;
789 }
790 attribute_length = *(u_int16_t*)(output + rule->offset);
791 break;
792 }
793 case ATTRIBUTE_LENGTH_OR_VALUE:
794 {
795 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
796 {
797 pld->destroy(pld);
798 return PARSE_ERROR;
799 }
800 attribute_length = *(u_int16_t*)(output + rule->offset);
801 break;
802 }
803 case ATTRIBUTE_VALUE:
804 {
805 if (attribute_format == FALSE)
806 {
807 if (this->parse_chunk(this, rule_number, output + rule->offset, attribute_length) != SUCCESS)
808 {
809 pld->destroy(pld);
810 return PARSE_ERROR;
811 }
812 }
813 break;
814 }
815 case NONCE_DATA:
816 {
817 size_t nonce_length = payload_length - NONCE_PAYLOAD_HEADER_LENGTH;
818 if (this->parse_chunk(this, rule_number, output + rule->offset, nonce_length) != SUCCESS)
819 {
820 pld->destroy(pld);
821 return PARSE_ERROR;
822 }
823 break;
824 }
825 case ID_DATA:
826 {
827 size_t data_length = payload_length - ID_PAYLOAD_HEADER_LENGTH;
828 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
829 {
830 pld->destroy(pld);
831 return PARSE_ERROR;
832 }
833 break;
834 }
835 case AUTH_DATA:
836 {
837 size_t data_length = payload_length - AUTH_PAYLOAD_HEADER_LENGTH;
838 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
839 {
840 pld->destroy(pld);
841 return PARSE_ERROR;
842 }
843 break;
844 }
845 case CERT_DATA:
846 {
847 size_t data_length = payload_length - CERT_PAYLOAD_HEADER_LENGTH;
848 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
849 {
850 pld->destroy(pld);
851 return PARSE_ERROR;
852 }
853 break;
854 }
855 case CERTREQ_DATA:
856 {
857 size_t data_length = payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH;
858 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
859 {
860 pld->destroy(pld);
861 return PARSE_ERROR;
862 }
863 break;
864 }
865 case EAP_DATA:
866 {
867 size_t data_length = payload_length - EAP_PAYLOAD_HEADER_LENGTH;
868 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
869 {
870 pld->destroy(pld);
871 return PARSE_ERROR;
872 }
873 break;
874 }
875 case SPIS:
876 {
877 size_t data_length = payload_length - DELETE_PAYLOAD_HEADER_LENGTH;
878 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
879 {
880 pld->destroy(pld);
881 return PARSE_ERROR;
882 }
883 break;
884 }
885 case VID_DATA:
886 {
887 size_t data_length = payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH;
888 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
889 {
890 pld->destroy(pld);
891 return PARSE_ERROR;
892 }
893 break;
894 }
895 case CONFIGURATION_ATTRIBUTE_VALUE:
896 {
897 size_t data_length = attribute_length;
898 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
899 {
900 pld->destroy(pld);
901 return PARSE_ERROR;
902 }
903 break;
904 }
905 case KEY_EXCHANGE_DATA:
906 {
907 size_t keydata_length = payload_length - KE_PAYLOAD_HEADER_LENGTH;
908 if (this->parse_chunk(this, rule_number, output + rule->offset, keydata_length) != SUCCESS)
909 {
910 pld->destroy(pld);
911 return PARSE_ERROR;
912 }
913 break;
914 }
915 case NOTIFICATION_DATA:
916 {
917 size_t notify_length = payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size;
918 if (this->parse_chunk(this, rule_number, output + rule->offset, notify_length) != SUCCESS)
919 {
920 pld->destroy(pld);
921 return PARSE_ERROR;
922 }
923 break;
924 }
925 case ENCRYPTED_DATA:
926 {
927 size_t data_length = payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH;
928 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
929 {
930 pld->destroy(pld);
931 return PARSE_ERROR;
932 }
933 break;
934 }
935 case TS_TYPE:
936 {
937 if (this->parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
938 {
939 pld->destroy(pld);
940 return PARSE_ERROR;
941 }
942 ts_type = *(u_int8_t*)(output + rule->offset);
943 break;
944 }
945 case ADDRESS:
946 {
947 size_t address_length = (ts_type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
948 if (this->parse_chunk(this, rule_number, output + rule->offset,address_length) != SUCCESS)
949 {
950 pld->destroy(pld);
951 return PARSE_ERROR;
952 }
953 break;
954 }
955 case TRAFFIC_SELECTORS:
956 {
957 size_t traffic_selectors_length = payload_length - TS_PAYLOAD_HEADER_LENGTH;
958 if (this->parse_list(this, rule_number, output + rule->offset, TRAFFIC_SELECTOR_SUBSTRUCTURE, traffic_selectors_length) != SUCCESS)
959 {
960 pld->destroy(pld);
961 return PARSE_ERROR;
962 }
963 break;
964 }
965 case UNKNOWN_PAYLOAD:
966 {
967 size_t unknown_payload_data_length = payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH;
968 if (this->parse_chunk(this, rule_number, output + rule->offset, unknown_payload_data_length) != SUCCESS)
969 {
970 pld->destroy(pld);
971 return PARSE_ERROR;
972 }
973 break;
974 }
975 default:
976 {
977 DBG1(DBG_ENC, " no rule to parse rule %d %N",
978 rule_number, encoding_type_names, rule->type);
979 pld->destroy(pld);
980 return PARSE_ERROR;
981 }
982 }
983 /* process next rulue */
984 rule++;
985 }
986
987 *payload = pld;
988 DBG2(DBG_ENC, "parsing %N payload finished",
989 payload_type_names, payload_type);
990 return SUCCESS;
991 }
992
993 /**
994 * Implementation of parser_t.get_remaining_byte_count.
995 */
996 static int get_remaining_byte_count (private_parser_t *this)
997 {
998 int count = (this->input_roof - this->byte_pos);
999 return count;
1000 }
1001
1002 /**
1003 * Implementation of parser_t.reset_context.
1004 */
1005 static void reset_context (private_parser_t *this)
1006 {
1007 this->byte_pos = this->input;
1008 this->bit_pos = 0;
1009 }
1010
1011 /**
1012 * Implementation of parser_t.destroy.
1013 */
1014 static void destroy(private_parser_t *this)
1015 {
1016 free(this);
1017 }
1018
1019 /*
1020 * Described in header.
1021 */
1022 parser_t *parser_create(chunk_t data)
1023 {
1024 private_parser_t *this = malloc_thing(private_parser_t);
1025
1026 this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**)) parse_payload;
1027 this->public.reset_context = (void(*)(parser_t*)) reset_context;
1028 this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count;
1029 this->public.destroy = (void(*)(parser_t*)) destroy;
1030
1031 this->parse_uint4 = parse_uint4;
1032 this->parse_uint8 = parse_uint8;
1033 this->parse_uint15 = parse_uint15;
1034 this->parse_uint16 = parse_uint16;
1035 this->parse_uint32 = parse_uint32;
1036 this->parse_uint64 = parse_uint64;
1037 this->parse_bytes = parse_bytes;
1038 this->parse_bit = parse_bit;
1039 this->parse_list = parse_list;
1040 this->parse_chunk = parse_chunk;
1041
1042 this->input = data.ptr;
1043 this->byte_pos = data.ptr;
1044 this->bit_pos = 0;
1045 this->input_roof = data.ptr + data.len;
1046
1047 return (parser_t*)this;
1048 }