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