- implemented and tested cert_payload_t
[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/certreq_payload.h>
48 #include <encoding/payloads/ts_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 * @brief 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 * @brief 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 * @brief 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 * @brief 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 * @brief 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 * @brief 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 * @brief 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 * @brief 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 * @brief Parse substructures in a list
172 *
173 * This function calls the parser recursivly 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 * @brief 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 * Assigned logger_t object.
232 */
233 logger_t *logger;
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 this->logger->log(this->logger, ERROR|MORE, " not enough input to parse rule %d %s",
244 rule_number, mapping_find(encoding_type_m,
245 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 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
269 rule_number, mapping_find(encoding_type_m,
270 this->rules[rule_number].type), this->bit_pos);
271 return PARSE_ERROR;
272 }
273
274 if (output_pos != NULL)
275 {
276 this->logger->log(this->logger, RAW|MOST, " => %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 this->logger->log(this->logger, ERROR|MORE, " not enough input to parse rule %d %s",
290 rule_number, mapping_find(encoding_type_m,
291 this->rules[rule_number].type));
292 return PARSE_ERROR;
293 }
294 if (this->bit_pos)
295 {
296 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
297 rule_number, mapping_find(encoding_type_m,
298 this->rules[rule_number].type), this->bit_pos);
299 return PARSE_ERROR;
300 }
301
302 /* caller interested in result ? */
303 if (output_pos != NULL)
304 {
305 *output_pos = *(this->byte_pos);
306 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
307 }
308 this->byte_pos++;
309
310 return SUCCESS;
311 }
312
313 /**
314 * Implementation of private_parser_t.parse_uint15.
315 */
316 static status_t parse_uint15(private_parser_t *this, int rule_number, u_int16_t *output_pos)
317 {
318 if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
319 {
320 this->logger->log(this->logger, ERROR|MORE, " not enough input to parse rule %d %s",
321 rule_number, mapping_find(encoding_type_m,
322 this->rules[rule_number].type));
323 return PARSE_ERROR;
324 }
325 if (this->bit_pos != 1)
326 {
327 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
328 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
329 this->bit_pos);
330 return PARSE_ERROR;
331 }
332 /* caller interested in result ? */
333 if (output_pos != NULL)
334 {
335 *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & ~0x8000;
336 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
337 }
338 this->byte_pos += 2;
339 this->bit_pos = 0;
340
341 return SUCCESS;
342 }
343
344 /**
345 * Implementation of private_parser_t.parse_uint16.
346 */
347 static status_t parse_uint16(private_parser_t *this, int rule_number, u_int16_t *output_pos)
348 {
349 if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
350 {
351 this->logger->log(this->logger, ERROR|MORE, " not enough input to parse rule %d %s",
352 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
353 return PARSE_ERROR;
354 }
355 if (this->bit_pos)
356 {
357 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
358 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
359 this->bit_pos);
360 return PARSE_ERROR;
361 }
362 /* caller interested in result ? */
363 if (output_pos != NULL)
364 {
365 *output_pos = ntohs(*((u_int16_t*)this->byte_pos));
366
367 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
368 }
369 this->byte_pos += 2;
370
371 return SUCCESS;
372 }
373 /**
374 * Implementation of private_parser_t.parse_uint32.
375 */
376 static status_t parse_uint32(private_parser_t *this, int rule_number, u_int32_t *output_pos)
377 {
378 if (this->byte_pos + sizeof(u_int32_t) > this->input_roof)
379 {
380 this->logger->log(this->logger, ERROR|MORE, " not enough input to parse rule %d %s",
381 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
382 return PARSE_ERROR;
383 }
384 if (this->bit_pos)
385 {
386 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
387 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
388 this->bit_pos);
389 return PARSE_ERROR;
390 }
391 /* caller interested in result ? */
392 if (output_pos != NULL)
393 {
394 *output_pos = ntohl(*((u_int32_t*)this->byte_pos));
395
396 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
397 }
398 this->byte_pos += 4;
399
400 return SUCCESS;
401 }
402
403 /**
404 * Implementation of private_parser_t.parse_uint64.
405 */
406 static status_t parse_uint64(private_parser_t *this, int rule_number, u_int64_t *output_pos)
407 {
408 if (this->byte_pos + sizeof(u_int64_t) > this->input_roof)
409 {
410 this->logger->log(this->logger, ERROR|MORE, " not enough input to parse rule %d %s",
411 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
412 return PARSE_ERROR;
413 }
414 if (this->bit_pos)
415 {
416 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
417 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
418 this->bit_pos);
419 return PARSE_ERROR;
420 }
421 /* caller interested in result ? */
422 if (output_pos != NULL)
423 {
424 /* assuming little endian host order */
425 *(output_pos + 1) = ntohl(*((u_int32_t*)this->byte_pos));
426 *output_pos = ntohl(*(((u_int32_t*)this->byte_pos) + 1));
427
428 this->logger->log_bytes(this->logger, RAW|MOST, " =>", (void*)output_pos, 8);
429 }
430 this->byte_pos += 8;
431
432 return SUCCESS;
433 }
434
435 /**
436 * Implementation of private_parser_t.parse_bytes.
437 */
438 static status_t parse_bytes (private_parser_t *this, int rule_number, u_int8_t *output_pos,size_t bytes)
439 {
440 if (this->byte_pos + bytes > this->input_roof)
441 {
442 this->logger->log(this->logger, ERROR|MORE, " not enough input to parse rule %d %s",
443 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
444 return PARSE_ERROR;
445 }
446 if (this->bit_pos)
447 {
448 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
449 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
450 this->bit_pos);
451 return PARSE_ERROR;
452 }
453
454 /* caller interested in result ? */
455 if (output_pos != NULL)
456 {
457 memcpy(output_pos,this->byte_pos,bytes);
458
459 this->logger->log_bytes(this->logger, RAW|MOST, " =>", (void*)output_pos, bytes);
460 }
461 this->byte_pos += bytes;
462
463 return SUCCESS;
464 }
465
466 /**
467 * Implementation of private_parser_t.parse_bit.
468 */
469 static status_t parse_bit(private_parser_t *this, int rule_number, bool *output_pos)
470 {
471 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
472 {
473 this->logger->log(this->logger, ERROR|MORE, " not enough input to parse rule %d %s",
474 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
475 return PARSE_ERROR;
476 }
477 /* caller interested in result ? */
478 if (output_pos != NULL)
479 {
480 u_int8_t mask;
481 mask = 0x01 << (7 - this->bit_pos);
482 *output_pos = *this->byte_pos & mask;
483
484 if (*output_pos)
485 {
486 /* set to a "clean", comparable true */
487 *output_pos = TRUE;
488 }
489
490 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
491 }
492 this->bit_pos = (this->bit_pos + 1) % 8;
493 if (this->bit_pos == 0)
494 {
495 this->byte_pos++;
496 }
497
498 return SUCCESS;
499 }
500
501 /**
502 * Implementation of private_parser_t.parse_list.
503 */
504 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)
505 {
506 linked_list_t * list = *output_pos;
507
508 if (length < 0)
509 {
510 this->logger->log(this->logger, ERROR|MORE, " invalid length for rule %d %s",
511 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
512 return PARSE_ERROR;
513 }
514
515 if (this->bit_pos)
516 {
517 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
518 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), this->bit_pos);
519 return PARSE_ERROR;
520 }
521
522 while (length > 0)
523 {
524 u_int8_t *pos_before = this->byte_pos;
525 payload_t *payload;
526 status_t status;
527 this->logger->log(this->logger, CONTROL|MORE, " %d bytes left, parsing recursivly %s",
528 length, mapping_find(payload_type_m, payload_type));
529 status = this->public.parse_payload((parser_t*)this, payload_type, &payload);
530 if (status != SUCCESS)
531 {
532 this->logger->log(this->logger, ERROR, " parsing of a %s substructure failed",
533 mapping_find(payload_type_m, payload_type));
534 return status;
535 }
536 list->insert_last(list, payload);
537 length -= this->byte_pos - pos_before;
538 }
539 *output_pos = list;
540 return SUCCESS;
541 }
542
543 /**
544 * Implementation of private_parser_t.parse_chunk.
545 */
546 static status_t parse_chunk(private_parser_t *this, int rule_number, chunk_t *output_pos, size_t length)
547 {
548 if (this->byte_pos + length > this->input_roof)
549 {
550 this->logger->log(this->logger, ERROR, " not enough input (%d bytes) to parse rule %d %s",
551 length, rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
552 return PARSE_ERROR;
553 }
554 if (this->bit_pos)
555 {
556 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
557 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), this->bit_pos);
558 return PARSE_ERROR;
559 }
560 if (output_pos != NULL)
561 {
562 output_pos->len = length;
563 output_pos->ptr = allocator_alloc(length);
564 memcpy(output_pos->ptr, this->byte_pos, length);
565 }
566 this->byte_pos += length;
567 this->logger->log_bytes(this->logger, RAW|MOST, " =>", (void*)output_pos->ptr, length);
568
569 return SUCCESS;
570 }
571
572 /**
573 * Implementation of parser_t.parse_payload.
574 */
575 static status_t parse_payload(private_parser_t *this, payload_type_t payload_type, payload_t **payload)
576 {
577 payload_t *pld;
578 void *output;
579 size_t rule_count, payload_length, spi_size, attribute_length;
580 u_int16_t ts_type;
581 bool attribute_format;
582 int rule_number;
583 encoding_rule_t *rule;
584
585 this->logger->log(this->logger, CONTROL|MORE, "parsing %s payload, %d bytes left",
586 mapping_find(payload_type_m, payload_type),
587 this->input_roof-this->byte_pos);
588
589 this->logger->log_bytes(this->logger, RAW, "parsing payload from", this->byte_pos,
590 this->input_roof-this->byte_pos);
591
592 /* ok, do the parsing */
593 pld = payload_create(payload_type);
594 if (pld == NULL)
595 {
596 this->logger->log(this->logger, ERROR, " payload %s not supported", mapping_find(payload_type_m, payload_type));
597 return NOT_SUPPORTED;
598 }
599 /* base pointer for output, avoids casting in every rule */
600 output = pld;
601
602 pld->get_encoding_rules(pld, &(this->rules), &rule_count);
603
604 for (rule_number = 0; rule_number < rule_count; rule_number++)
605 {
606 rule = &(this->rules[rule_number]);
607 this->logger->log(this->logger, CONTROL|MOST, " parsing rule %d %s",
608 rule_number, mapping_find(encoding_type_m, rule->type));
609 switch (rule->type)
610 {
611 case U_INT_4:
612 {
613 if (this->parse_uint4(this, rule_number, output + rule->offset) != SUCCESS)
614 {
615 pld->destroy(pld);
616 return PARSE_ERROR;
617 }
618 break;
619 }
620 case U_INT_8:
621 {
622 if (this->parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
623 {
624 pld->destroy(pld);
625 return PARSE_ERROR;
626 }
627 break;
628 }
629 case U_INT_16:
630 {
631 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
632 {
633 pld->destroy(pld);
634 return PARSE_ERROR;
635 }
636 break;
637 }
638 case U_INT_32:
639 {
640 if (this->parse_uint32(this, rule_number, output + rule->offset) != SUCCESS)
641 {
642 pld->destroy(pld);
643 return PARSE_ERROR;
644 }
645 break;
646 }
647 case U_INT_64:
648 {
649 if (this->parse_uint64(this, rule_number, output + rule->offset) != SUCCESS)
650 {
651 pld->destroy(pld);
652 return PARSE_ERROR;
653 }
654 break;
655 }
656 case IKE_SPI:
657 {
658 if (this->parse_bytes(this, rule_number, output + rule->offset,8) != SUCCESS)
659 {
660 pld->destroy(pld);
661 return PARSE_ERROR;
662 }
663 break;
664 }
665 case RESERVED_BIT:
666 {
667 if (this->parse_bit(this, rule_number, NULL) != SUCCESS)
668 {
669 pld->destroy(pld);
670 return PARSE_ERROR;
671 }
672 break;
673 }
674 case RESERVED_BYTE:
675 {
676 if (this->parse_uint8(this, rule_number, NULL) != SUCCESS)
677 {
678 pld->destroy(pld);
679 return PARSE_ERROR;
680 }
681 break;
682 }
683 case FLAG:
684 {
685 if (this->parse_bit(this, rule_number, output + rule->offset) != SUCCESS)
686 {
687 pld->destroy(pld);
688 return PARSE_ERROR;
689 }
690 break;
691 }
692 case PAYLOAD_LENGTH:
693 {
694 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
695 {
696 pld->destroy(pld);
697 return PARSE_ERROR;
698 }
699 payload_length = *(u_int16_t*)(output + rule->offset);
700 break;
701 }
702 case HEADER_LENGTH:
703 {
704 if (this->parse_uint32(this, rule_number, output + rule->offset) != SUCCESS)
705 {
706 pld->destroy(pld);
707 return PARSE_ERROR;
708 }
709 break;
710 }
711 case SPI_SIZE:
712 {
713 if (this->parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
714 {
715 pld->destroy(pld);
716 return PARSE_ERROR;
717 }
718 spi_size = *(u_int8_t*)(output + rule->offset);
719 break;
720 }
721 case SPI:
722 {
723 if (this->parse_chunk(this, rule_number, output + rule->offset, spi_size) != SUCCESS)
724 {
725 pld->destroy(pld);
726 return PARSE_ERROR;
727 }
728 break;
729 }
730 case PROPOSALS:
731 {
732 size_t proposals_length = payload_length - SA_PAYLOAD_HEADER_LENGTH;
733 if (this->parse_list(this, rule_number, output + rule->offset, PROPOSAL_SUBSTRUCTURE, proposals_length) != SUCCESS)
734 {
735 pld->destroy(pld);
736 return PARSE_ERROR;
737 }
738 break;
739 }
740 case TRANSFORMS:
741 {
742 size_t transforms_length = payload_length - spi_size - PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH;
743 if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_SUBSTRUCTURE, transforms_length) != SUCCESS)
744 {
745 pld->destroy(pld);
746 return PARSE_ERROR;
747 }
748 break;
749 }
750 case TRANSFORM_ATTRIBUTES:
751 {
752 size_t transform_a_length = payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
753 if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_ATTRIBUTE, transform_a_length) != SUCCESS)
754 {
755 pld->destroy(pld);
756 return PARSE_ERROR;
757 }
758 break;
759 }
760 case ATTRIBUTE_FORMAT:
761 {
762 if (this->parse_bit(this, rule_number, output + rule->offset) != SUCCESS)
763 {
764 pld->destroy(pld);
765 return PARSE_ERROR;
766 }
767 attribute_format = *(bool*)(output + rule->offset);
768 break;
769 }
770 case ATTRIBUTE_TYPE:
771 {
772 if (this->parse_uint15(this, rule_number, output + rule->offset) != SUCCESS)
773 {
774 pld->destroy(pld);
775 return PARSE_ERROR;
776 }
777 attribute_format = *(bool*)(output + rule->offset);
778 break;
779 }
780 case ATTRIBUTE_LENGTH_OR_VALUE:
781 {
782 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
783 {
784 pld->destroy(pld);
785 return PARSE_ERROR;
786 }
787 attribute_length = *(u_int16_t*)(output + rule->offset);
788 break;
789 }
790 case ATTRIBUTE_VALUE:
791 {
792 if (attribute_format == FALSE)
793 {
794 if (this->parse_chunk(this, rule_number, output + rule->offset, attribute_length) != SUCCESS)
795 {
796 pld->destroy(pld);
797 return PARSE_ERROR;
798 }
799 }
800 break;
801 }
802 case NONCE_DATA:
803 {
804 size_t nonce_length = payload_length - NONCE_PAYLOAD_HEADER_LENGTH;
805 if (this->parse_chunk(this, rule_number, output + rule->offset, nonce_length) != SUCCESS)
806 {
807 pld->destroy(pld);
808 return PARSE_ERROR;
809 }
810 break;
811 }
812 case ID_DATA:
813 {
814 size_t data_length = payload_length - ID_PAYLOAD_HEADER_LENGTH;
815 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
816 {
817 pld->destroy(pld);
818 return PARSE_ERROR;
819 }
820 break;
821 }
822 case AUTH_DATA:
823 {
824 size_t data_length = payload_length - AUTH_PAYLOAD_HEADER_LENGTH;
825 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
826 {
827 pld->destroy(pld);
828 return PARSE_ERROR;
829 }
830 break;
831 }
832 case CERT_DATA:
833 {
834 size_t data_length = payload_length - CERT_PAYLOAD_HEADER_LENGTH;
835 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
836 {
837 pld->destroy(pld);
838 return PARSE_ERROR;
839 }
840 break;
841 }
842 case CERTREQ_DATA:
843 {
844 size_t data_length = payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH;
845 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
846 {
847 pld->destroy(pld);
848 return PARSE_ERROR;
849 }
850 break;
851 }
852 case KEY_EXCHANGE_DATA:
853 {
854 size_t keydata_length = payload_length - KE_PAYLOAD_HEADER_LENGTH;
855 if (this->parse_chunk(this, rule_number, output + rule->offset, keydata_length) != SUCCESS)
856 {
857 pld->destroy(pld);
858 return PARSE_ERROR;
859 }
860 break;
861 }
862 case NOTIFICATION_DATA:
863 {
864 size_t notify_length = payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size;
865 if (this->parse_chunk(this, rule_number, output + rule->offset, notify_length) != SUCCESS)
866 {
867 pld->destroy(pld);
868 return PARSE_ERROR;
869 }
870 break;
871 }
872 case ENCRYPTED_DATA:
873 {
874 size_t data_length = payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH;
875 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
876 {
877 pld->destroy(pld);
878 return PARSE_ERROR;
879 }
880 break;
881 }
882 case TS_TYPE:
883 {
884 if (this->parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
885 {
886 pld->destroy(pld);
887 return PARSE_ERROR;
888 }
889 ts_type = *(u_int8_t*)(output + rule->offset);
890 break;
891 }
892 case ADDRESS:
893 {
894 size_t address_length = (ts_type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
895 if (this->parse_chunk(this, rule_number, output + rule->offset,address_length) != SUCCESS)
896 {
897 pld->destroy(pld);
898 return PARSE_ERROR;
899 }
900 break;
901 }
902 case TRAFFIC_SELECTORS:
903 {
904 size_t traffic_selectors_length = payload_length - TS_PAYLOAD_HEADER_LENGTH;
905 if (this->parse_list(this, rule_number, output + rule->offset, TRAFFIC_SELECTOR_SUBSTRUCTURE, traffic_selectors_length) != SUCCESS)
906 {
907 pld->destroy(pld);
908 return PARSE_ERROR;
909 }
910 break;
911 }
912 default:
913 {
914 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);
915 pld->destroy(pld);
916 return PARSE_ERROR;
917 }
918 }
919 /* process next rulue */
920 rule++;
921 }
922
923 *payload = pld;
924
925 return SUCCESS;
926 }
927
928 /**
929 * Implementation of parser_t.get_remaining_byte_count.
930 */
931 static int get_remaining_byte_count (private_parser_t *this)
932 {
933 int count = (this->input_roof - this->byte_pos);
934 return count;
935 }
936
937 /**
938 * Implementation of parser_t.reset_context.
939 */
940 static void reset_context (private_parser_t *this)
941 {
942 this->byte_pos = this->input;
943 this->bit_pos = 0;
944 }
945
946 /**
947 * Implementation of parser_t.destroy.
948 */
949 static void destroy(private_parser_t *this)
950 {
951 charon->logger_manager->destroy_logger(charon->logger_manager,this->logger);
952 allocator_free(this);
953 }
954
955 /*
956 * Described in header.
957 */
958 parser_t *parser_create(chunk_t data)
959 {
960 private_parser_t *this = allocator_alloc_thing(private_parser_t);
961
962 this->logger = charon->logger_manager->create_logger(charon->logger_manager, PARSER, NULL);
963
964 this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**)) parse_payload;
965 this->public.reset_context = (void(*)(parser_t*)) reset_context;
966 this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count;
967 this->public.destroy = (void(*)(parser_t*)) destroy;
968
969
970 this->parse_uint4 = parse_uint4;
971 this->parse_uint8 = parse_uint8;
972 this->parse_uint15 = parse_uint15;
973 this->parse_uint16 = parse_uint16;
974 this->parse_uint32 = parse_uint32;
975 this->parse_uint64 = parse_uint64;
976 this->parse_bytes = parse_bytes;
977 this->parse_bit = parse_bit;
978 this->parse_list = parse_list;
979 this->parse_chunk = parse_chunk;
980
981 this->input = data.ptr;
982 this->byte_pos = data.ptr;
983 this->bit_pos = 0;
984 this->input_roof = data.ptr + data.len;
985
986 return (parser_t*)this;
987 }
988