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