4 * @brief Implementation of message_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
29 #include <sa/ike_sa_id.h>
30 #include <encoding/generator.h>
31 #include <encoding/parser.h>
32 #include <utils/linked_list.h>
33 #include <utils/allocator.h>
34 #include <utils/logger_manager.h>
35 #include <encoding/payloads/encodings.h>
36 #include <encoding/payloads/payload.h>
37 #include <encoding/payloads/encryption_payload.h>
40 typedef struct supported_payload_entry_t supported_payload_entry_t
;
43 * Supported payload entry used in message_rule_t.
46 struct supported_payload_entry_t
{
50 payload_type_t payload_type
;
53 * Minimal occurence of this payload.
58 * Max occurence of this payload.
63 typedef struct message_rule_t message_rule_t
;
66 * Message Rule used to find out which payloads
67 * are supported by each message type.
70 struct message_rule_t
{
74 exchange_type_t exchange_type
;
77 * Is message a request or response.
81 * Number of supported payloads.
83 size_t supported_payloads_count
;
85 * Pointer to first supported payload entry.
87 supported_payload_entry_t
*supported_payloads
;
91 * Message rule for IKE_SA_INIT from initiator.
93 static supported_payload_entry_t supported_ike_sa_init_i_payloads
[] =
95 {SECURITY_ASSOCIATION
,1,1},
101 * Message rule for IKE_SA_INIT from responder.
103 static supported_payload_entry_t supported_ike_sa_init_r_payloads
[] =
105 {SECURITY_ASSOCIATION
,1,1},
112 * Message rules, defines allowed payloads.
114 static message_rule_t message_rules
[] = {
115 {IKE_SA_INIT
,TRUE
,(sizeof(supported_ike_sa_init_i_payloads
)/sizeof(supported_payload_entry_t
)),supported_ike_sa_init_i_payloads
},
116 {IKE_SA_INIT
,FALSE
,(sizeof(supported_ike_sa_init_r_payloads
)/sizeof(supported_payload_entry_t
)),supported_ike_sa_init_r_payloads
}
119 typedef struct payload_entry_t payload_entry_t
;
122 * Entry for a payload in the internal used linked list.
125 struct payload_entry_t
{
129 payload_type_t payload_type
;
131 * Data struct holding the data of given payload.
137 typedef struct private_message_t private_message_t
;
140 * Private data of an message_t object.
142 struct private_message_t
{
145 * Public part of a message_t object.
150 * Minor version of message.
152 u_int8_t major_version
;
155 * Major version of message.
157 u_int8_t minor_version
;
160 * First Payload in message.
162 payload_type_t first_payload
;
165 * Assigned exchange type.
167 exchange_type_t exchange_type
;
171 * TRUE if message is request.
172 * FALSE if message is reply.
177 * Message ID of this message.
179 u_int32_t message_id
;
182 * ID of assigned IKE_SA.
184 ike_sa_id_t
*ike_sa_id
;
187 * Assigned UDP packet.
189 * Stores incoming packet or last generated one.
194 * Linked List where payload data are stored in.
196 linked_list_t
*payloads
;
199 * Assigned parser to parse Header and Body of this message.
209 * Gets a list of supported payloads of this message type
211 * @param this calling object
212 * @param[out] supported_payloads first entry of supported payloads
213 * @param[out] supported_payloads_count number of supported payload entries
217 * - NOT_FOUND if no supported payload definition could be found
219 status_t (*get_supported_payloads
) (private_message_t
*this, supported_payload_entry_t
**supported_payloads
,size_t *supported_payloads_count
);
224 * Implementation of private_message_t.get_supported_payloads.
226 status_t
get_supported_payloads (private_message_t
*this, supported_payload_entry_t
**supported_payloads
,size_t *supported_payloads_count
)
229 exchange_type_t exchange_type
= this->public.get_exchange_type(&(this->public));
230 bool is_request
= this->public.get_request(&(this->public));
233 for (i
= 0; i
< (sizeof(message_rules
) / sizeof(message_rule_t
)); i
++)
235 if ((exchange_type
== message_rules
[i
].exchange_type
) &&
236 (is_request
== message_rules
[i
].is_request
))
238 /* found rule for given exchange_type*/
239 *supported_payloads
= message_rules
[i
].supported_payloads
;
240 *supported_payloads_count
= message_rules
[i
].supported_payloads_count
;
247 *supported_payloads
= NULL
;
248 *supported_payloads_count
= 0;
253 * Implementation of message_t.set_ike_sa_id.
255 static void set_ike_sa_id (private_message_t
*this,ike_sa_id_t
*ike_sa_id
)
257 this->ike_sa_id
= ike_sa_id
->clone(ike_sa_id
);
261 * Implementation of message_t.get_ike_sa_id.
263 static status_t
get_ike_sa_id (private_message_t
*this,ike_sa_id_t
**ike_sa_id
)
265 if (this->ike_sa_id
== NULL
)
269 *ike_sa_id
= this->ike_sa_id
->clone(this->ike_sa_id
);
274 * Implementation of message_t.set_message_id.
276 static void set_message_id (private_message_t
*this,u_int32_t message_id
)
278 this->message_id
= message_id
;
282 * Implementation of message_t.get_message_id.
284 static u_int32_t
get_message_id (private_message_t
*this)
286 return this->message_id
;
290 * Implementation of message_t.get_responder_spi.
292 static u_int64_t
get_responder_spi (private_message_t
*this)
294 return (this->ike_sa_id
->get_responder_spi(this->ike_sa_id
));
298 * Implementation of message_t.set_major_version.
300 static void set_major_version (private_message_t
*this,u_int8_t major_version
)
302 this->major_version
= major_version
;
307 * Implementation of message_t.set_major_version.
309 static u_int8_t
get_major_version (private_message_t
*this)
311 return this->major_version
;
315 * Implementation of message_t.set_minor_version.
317 static void set_minor_version (private_message_t
*this,u_int8_t minor_version
)
319 this->minor_version
= minor_version
;
323 * Implementation of message_t.get_minor_version.
325 static u_int8_t
get_minor_version (private_message_t
*this)
327 return this->minor_version
;
331 * Implementation of message_t.set_exchange_type.
333 static void set_exchange_type (private_message_t
*this,exchange_type_t exchange_type
)
335 this->exchange_type
= exchange_type
;
339 * Implementation of message_t.get_exchange_type.
341 static exchange_type_t
get_exchange_type (private_message_t
*this)
343 return this->exchange_type
;
347 * Implementation of message_t.set_request.
349 static void set_request (private_message_t
*this,bool request
)
351 this->is_request
= request
;
355 * Implementation of message_t.get_request.
357 static exchange_type_t
get_request (private_message_t
*this)
359 return this->is_request
;
363 * Implementation of message_t.add_payload.
365 static void add_payload(private_message_t
*this, payload_t
*payload
)
367 payload_t
*last_payload
;
368 if (this->payloads
->get_count(this->payloads
) > 0)
370 this->payloads
->get_last(this->payloads
,(void **) &last_payload
);
373 this->payloads
->insert_last(this->payloads
, payload
);
375 if (this->payloads
->get_count(this->payloads
) == 1)
377 this->first_payload
= payload
->get_type(payload
);
381 last_payload
->set_next_type(last_payload
,payload
->get_type(payload
));
384 this->logger
->log(this->logger
, CONTROL
|MORE
, "added payload of type %s to message",
385 mapping_find(payload_type_m
, payload
->get_type(payload
)));
390 * Implementation of message_t.set_source.
392 static void set_source(private_message_t
*this, host_t
*host
)
394 if (this->packet
->source
!= NULL
)
396 this->packet
->source
->destroy(this->packet
->source
);
398 this->packet
->source
= host
;
402 * Implementation of message_t.set_destination.
404 static void set_destination(private_message_t
*this, host_t
*host
)
406 if (this->packet
->destination
!= NULL
)
408 this->packet
->destination
->destroy(this->packet
->destination
);
410 this->packet
->destination
= host
;
414 * Implementation of message_t.get_source.
416 static void get_source(private_message_t
*this, host_t
**host
)
418 *host
= this->packet
->source
;
422 * Implementation of message_t.get_destination.
424 static void get_destination(private_message_t
*this, host_t
**host
)
426 *host
= this->packet
->destination
;
430 * Implementation of message_t.get_destination.
432 static iterator_t
*get_payload_iterator(private_message_t
*this)
434 return this->payloads
->create_iterator(this->payloads
, TRUE
);
439 * Implementation of message_t.generate.
441 static status_t
generate(private_message_t
*this, crypter_t
*crypter
, signer_t
* signer
, packet_t
**packet
)
443 generator_t
*generator
;
444 ike_header_t
*ike_header
;
445 payload_t
*payload
, *next_payload
;
446 iterator_t
*iterator
;
450 this->logger
->log(this->logger
, CONTROL
, "generating message, contains %d payloads",
451 this->payloads
->get_count(this->payloads
));
453 if (this->exchange_type
== EXCHANGE_TYPE_UNDEFINED
)
455 this->logger
->log(this->logger
, ERROR
, "exchange type is not defined");
456 return INVALID_STATE
;
459 if (this->packet
->source
== NULL
||
460 this->packet
->destination
== NULL
)
462 this->logger
->log(this->logger
, ERROR
, "source/destination not defined");
463 return INVALID_STATE
;
466 /* build ike header */
467 ike_header
= ike_header_create();
469 ike_header
->set_exchange_type(ike_header
, this->exchange_type
);
470 ike_header
->set_message_id(ike_header
, this->message_id
);
471 ike_header
->set_response_flag(ike_header
, !this->is_request
);
472 ike_header
->set_initiator_flag(ike_header
, this->ike_sa_id
->is_initiator(this->ike_sa_id
));
473 ike_header
->set_initiator_spi(ike_header
, this->ike_sa_id
->get_initiator_spi(this->ike_sa_id
));
474 ike_header
->set_responder_spi(ike_header
, this->ike_sa_id
->get_responder_spi(this->ike_sa_id
));
476 generator
= generator_create();
478 payload
= (payload_t
*)ike_header
;
480 iterator
= this->payloads
->create_iterator(this->payloads
, TRUE
);
482 /* generate every payload, except last one */
483 while(iterator
->has_next(iterator
))
485 iterator
->current(iterator
, (void**)&next_payload
);
486 payload
->set_next_type(payload
, next_payload
->get_type(next_payload
));
487 generator
->generate_payload(generator
, payload
);
489 payload
= next_payload
;
491 iterator
->destroy(iterator
);
493 /* build last payload */
494 payload
->set_next_type(payload
, NO_PAYLOAD
);
495 /* if it's an encryption payload, build it first */
496 if (payload
->get_type(payload
) == ENCRYPTED
)
498 encryption_payload_t
*encryption_payload
= (encryption_payload_t
*)payload
;
499 encryption_payload
->set_signer(encryption_payload
, signer
);
500 status
= encryption_payload
->encrypt(encryption_payload
, crypter
);
501 if (status
!= SUCCESS
)
503 generator
->destroy(generator
);
504 ike_header
->destroy(ike_header
);
508 generator
->generate_payload(generator
, payload
);
509 ike_header
->destroy(ike_header
);
512 if (this->packet
->data
.ptr
!= NULL
)
514 allocator_free(this->packet
->data
.ptr
);
516 generator
->write_to_chunk(generator
, &(this->packet
->data
));
517 generator
->destroy(generator
);
519 /* append integrity checksum if necessary */
520 if (payload
->get_type(payload
) == ENCRYPTED
)
522 encryption_payload_t
*encryption_payload
= (encryption_payload_t
*)payload
;
523 status
= encryption_payload
->build_signature(encryption_payload
, this->packet
->data
);
524 if (status
!= SUCCESS
)
530 /* clone packet for caller */
531 *packet
= this->packet
->clone(this->packet
);
533 this->logger
->log(this->logger
, CONTROL
, "message generated successfully");
538 * Implements message_t.parse_header.
540 static status_t
parse_header(private_message_t
*this)
542 ike_header_t
*ike_header
;
546 this->logger
->log(this->logger
, CONTROL
, "parsing header of message");
548 this->parser
->reset_context(this->parser
);
549 status
= this->parser
->parse_payload(this->parser
,HEADER
,(payload_t
**) &ike_header
);
550 if (status
!= SUCCESS
)
552 this->logger
->log(this->logger
, ERROR
, "Header could not be parsed");
558 status
= ike_header
->payload_interface
.verify(&(ike_header
->payload_interface
));
559 if (status
!= SUCCESS
)
561 this->logger
->log(this->logger
, ERROR
, "Header verification failed");
562 ike_header
->destroy(ike_header
);
566 if (this->ike_sa_id
!= NULL
)
568 this->ike_sa_id
->destroy(this->ike_sa_id
);
571 this->ike_sa_id
= ike_sa_id_create(ike_header
->get_initiator_spi(ike_header
),
572 ike_header
->get_responder_spi(ike_header
),
573 ike_header
->get_initiator_flag(ike_header
));
575 this->exchange_type
= ike_header
->get_exchange_type(ike_header
);
576 this->message_id
= ike_header
->get_message_id(ike_header
);
577 this->is_request
= (!(ike_header
->get_response_flag(ike_header
)));
578 this->major_version
= ike_header
->get_maj_version(ike_header
);
579 this->minor_version
= ike_header
->get_min_version(ike_header
);
580 this->first_payload
= ike_header
->payload_interface
.get_next_type(&(ike_header
->payload_interface
));
583 this->logger
->log(this->logger
, CONTROL
, "parsing header successfully");
585 ike_header
->destroy(ike_header
);
590 * Implements message_t.parse_body.
592 static status_t
parse_body(private_message_t
*this, crypter_t
*crypter
, signer_t
*signer
)
594 status_t status
= SUCCESS
;
595 payload_type_t current_payload_type
= this->first_payload
;
597 this->logger
->log(this->logger
, CONTROL
, "parsing body of message");
599 while (current_payload_type
!= NO_PAYLOAD
)
601 payload_t
*current_payload
;
603 this->logger
->log(this->logger
, CONTROL
|MORE
, "start parsing payload of type %s",
604 mapping_find(payload_type_m
, current_payload_type
));
606 status
= this->parser
->parse_payload(this->parser
,current_payload_type
,(payload_t
**) ¤t_payload
);
607 if (status
!= SUCCESS
)
609 this->logger
->log(this->logger
, ERROR
, "payload type %s could not be parsed",mapping_find(payload_type_m
,current_payload_type
));
613 status
= current_payload
->verify(current_payload
);
614 if (status
!= SUCCESS
)
616 this->logger
->log(this->logger
, ERROR
, "payload type %s could not be verified",mapping_find(payload_type_m
,current_payload_type
));
617 status
= VERIFY_ERROR
;
621 /* encrypted payload must be decrypted */
622 if (current_payload
->get_type(current_payload
) == ENCRYPTED
)
624 encryption_payload_t
*encryption_payload
= (encryption_payload_t
*)current_payload
;
625 encryption_payload
->set_signer(encryption_payload
, signer
);
626 status
= encryption_payload
->verify_signature(encryption_payload
, this->packet
->data
);
627 if (status
!= SUCCESS
)
629 this->logger
->log(this->logger
, ERROR
, "encryption payload signature invaild");
632 status
= encryption_payload
->decrypt(encryption_payload
, crypter
);
633 if (status
!= SUCCESS
)
635 this->logger
->log(this->logger
, ERROR
, "parsing decrypted encryption payload failed");
640 /* get next payload type */
641 current_payload_type
= current_payload
->get_next_type(current_payload
);
643 this->payloads
->insert_last(this->payloads
,current_payload
);
646 return this->public.verify(&(this->public));
651 * implements message_t.verify
653 static status_t
verify(private_message_t
*this)
655 iterator_t
*iterator
;
658 supported_payload_entry_t
*supported_payloads
;
659 size_t supported_payloads_count
;
661 this->logger
->log(this->logger
, CONTROL
|MORE
, "verifying message");
663 status
= this->get_supported_payloads(this, &supported_payloads
, &supported_payloads_count
);
664 if (status
!= SUCCESS
)
666 this->logger
->log(this->logger
, ERROR
, "could not get supported payloads: %s");
669 iterator
= this->payloads
->create_iterator(this->payloads
,TRUE
);
670 /* check for payloads with wrong count*/
671 for (i
= 0; i
< supported_payloads_count
;i
++)
673 size_t min_occurence
= supported_payloads
[i
].min_occurence
;
674 size_t max_occurence
= supported_payloads
[i
].max_occurence
;
675 payload_type_t payload_type
= supported_payloads
[i
].payload_type
;
676 size_t found_payloads
= 0;
678 iterator
->reset(iterator
);
680 while(iterator
->has_next(iterator
))
682 payload_t
*current_payload
;
683 iterator
->current(iterator
,(void **)¤t_payload
);
686 if (current_payload
->get_type(current_payload
) == payload_type
)
689 if (found_payloads
> max_occurence
)
691 this->logger
->log(this->logger
, ERROR
, "Payload of type %s more than %d times (%d) occured in current message",
692 mapping_find(payload_type_m
,current_payload
->get_type(current_payload
)),max_occurence
,found_payloads
);
693 iterator
->destroy(iterator
);
694 return NOT_SUPPORTED
;
698 if (found_payloads
< min_occurence
)
700 this->logger
->log(this->logger
, ERROR
, "Payload of type %s not occured %d times",
701 mapping_find(payload_type_m
,payload_type
),min_occurence
);
702 iterator
->destroy(iterator
);
703 return NOT_SUPPORTED
;
706 iterator
->destroy(iterator
);
713 * Implements message_t's destroy function.
714 * See #message_s.destroy.
716 static void destroy (private_message_t
*this)
718 iterator_t
*iterator
;
720 this->packet
->destroy(this->packet
);
722 if (this->ike_sa_id
!= NULL
)
724 this->ike_sa_id
->destroy(this->ike_sa_id
);
727 iterator
= this->payloads
->create_iterator(this->payloads
, TRUE
);
728 while (iterator
->has_next(iterator
))
731 iterator
->current(iterator
, (void**)&payload
);
732 this->logger
->log(this->logger
, CONTROL
|MOST
, "Destroying payload of type %s",
733 mapping_find(payload_type_m
, payload
->get_type(payload
)));
734 payload
->destroy(payload
);
736 iterator
->destroy(iterator
);
737 this->payloads
->destroy(this->payloads
);
738 this->parser
->destroy(this->parser
);
739 global_logger_manager
->destroy_logger(global_logger_manager
, this->logger
);
741 allocator_free(this);
745 * Described in Header-File
747 message_t
*message_create_from_packet(packet_t
*packet
)
749 private_message_t
*this = allocator_alloc_thing(private_message_t
);
751 /* public functions */
752 this->public.set_major_version
= (void(*)(message_t
*, u_int8_t
))set_major_version
;
753 this->public.get_major_version
= (u_int8_t(*)(message_t
*))get_major_version
;
754 this->public.set_minor_version
= (void(*)(message_t
*, u_int8_t
))set_minor_version
;
755 this->public.get_minor_version
= (u_int8_t(*)(message_t
*))get_minor_version
;
756 this->public.set_message_id
= (void(*)(message_t
*, u_int32_t
))set_message_id
;
757 this->public.get_message_id
= (u_int32_t(*)(message_t
*))get_message_id
;
758 this->public.get_responder_spi
= (u_int64_t(*)(message_t
*))get_responder_spi
;
759 this->public.set_ike_sa_id
= (void(*)(message_t
*, ike_sa_id_t
*))set_ike_sa_id
;
760 this->public.get_ike_sa_id
= (status_t(*)(message_t
*, ike_sa_id_t
**))get_ike_sa_id
;
761 this->public.set_exchange_type
= (void(*)(message_t
*, exchange_type_t
))set_exchange_type
;
762 this->public.get_exchange_type
= (exchange_type_t(*)(message_t
*))get_exchange_type
;
763 this->public.set_request
= (void(*)(message_t
*, bool))set_request
;
764 this->public.get_request
= (bool(*)(message_t
*))get_request
;
765 this->public.add_payload
= (void(*)(message_t
*,payload_t
*))add_payload
;
766 this->public.generate
= (status_t (*) (message_t
*,crypter_t
*,signer_t
*,packet_t
**)) generate
;
767 this->public.set_source
= (void (*) (message_t
*,host_t
*)) set_source
;
768 this->public.get_source
= (void (*) (message_t
*,host_t
**)) get_source
;
769 this->public.set_destination
= (void (*) (message_t
*,host_t
*)) set_destination
;
770 this->public.get_destination
= (void (*) (message_t
*,host_t
**)) get_destination
;
771 this->public.get_payload_iterator
= (iterator_t
* (*) (message_t
*)) get_payload_iterator
;
772 this->public.parse_header
= (status_t (*) (message_t
*)) parse_header
;
773 this->public.parse_body
= (status_t (*) (message_t
*,crypter_t
*,signer_t
*)) parse_body
;
774 this->public.verify
= (status_t (*) (message_t
*)) verify
;
775 this->public.destroy
= (void(*)(message_t
*))destroy
;
778 this->exchange_type
= EXCHANGE_TYPE_UNDEFINED
;
779 this->is_request
= TRUE
;
780 this->ike_sa_id
= NULL
;
781 this->first_payload
= NO_PAYLOAD
;
782 this->message_id
= 0;
784 /* private functions */
785 this->get_supported_payloads
= get_supported_payloads
;
790 packet
= packet_create();
792 this->packet
= packet
;
793 this->payloads
= linked_list_create();
795 /* parser is created from data of packet */
796 this->parser
= parser_create(this->packet
->data
);
798 this->logger
= global_logger_manager
->create_logger(global_logger_manager
, MESSAGE
, NULL
);
800 return (&this->public);
804 * Described in Header-File
806 message_t
*message_create()
808 return message_create_from_packet(NULL
);