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