4 * @brief Class message_t. Object of this type represents an IKEv2-Message.
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 are supported by each message type
69 struct message_rule_t
{
73 exchange_type_t exchange_type
;
76 * Is message a request or response
80 * Number of supported payloads
82 size_t supported_payloads_count
;
84 * Pointer to first supported payload entry
86 supported_payload_entry_t
*supported_payloads
;
90 * message rule for ike_sa_init from initiator
92 static supported_payload_entry_t supported_ike_sa_init_i_payloads
[] =
94 {SECURITY_ASSOCIATION
,1,1},
100 * message rule for ike_sa_init from responder
102 static supported_payload_entry_t supported_ike_sa_init_r_payloads
[] =
104 {SECURITY_ASSOCIATION
,1,1},
111 * message rules, defines allowed payloads
113 static message_rule_t message_rules
[] = {
114 {IKE_SA_INIT
,TRUE
,(sizeof(supported_ike_sa_init_i_payloads
)/sizeof(supported_payload_entry_t
)),supported_ike_sa_init_i_payloads
},
115 {IKE_SA_INIT
,FALSE
,(sizeof(supported_ike_sa_init_r_payloads
)/sizeof(supported_payload_entry_t
)),supported_ike_sa_init_r_payloads
}
118 typedef struct payload_entry_t payload_entry_t
;
121 * Entry for a payload in the internal used linked list
124 struct payload_entry_t
{
128 payload_type_t payload_type
;
130 * Data struct holding the data of given payload
136 typedef struct private_message_t private_message_t
;
139 * Private data of an message_t object
141 struct private_message_t
{
144 * 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
204 * logger for 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
216 * NOT_FOUND if no supported payload definition could be found
218 status_t (*get_supported_payloads
) (private_message_t
*this, supported_payload_entry_t
**supported_payloads
,size_t *supported_payloads_count
);
223 * Implements private_message_t's get_supported_payloads function.
224 * See #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 * Implements message_t's set_ike_sa_id function.
254 * See #message_s.set_ike_sa_id.
256 static status_t
set_ike_sa_id (private_message_t
*this,ike_sa_id_t
*ike_sa_id
)
259 status
= ike_sa_id
->clone(ike_sa_id
,&(this->ike_sa_id
));
264 * Implements message_t's get_ike_sa_id function.
265 * See #message_s.get_ike_sa_id.
267 static status_t
get_ike_sa_id (private_message_t
*this,ike_sa_id_t
**ike_sa_id
)
270 if (this->ike_sa_id
== NULL
)
274 status
= this->ike_sa_id
->clone(this->ike_sa_id
,ike_sa_id
);
280 * Implements message_t's set_message_id function.
281 * See #message_s.set_message_id.
283 static status_t
set_message_id (private_message_t
*this,u_int32_t message_id
)
285 this->message_id
= message_id
;
291 * Implements message_t's set_message_id function.
292 * See #message_s.set_message_id.
294 static u_int32_t
get_message_id (private_message_t
*this)
296 return this->message_id
;
300 * Implements message_t's get_responder_spi function.
301 * See #message_s.get_responder_spi.
303 static u_int64_t
get_responder_spi (private_message_t
*this)
305 return (this->ike_sa_id
->get_responder_spi(this->ike_sa_id
));
309 * Implements message_t's set_major_version function.
310 * See #message_s.set_major_version.
312 static status_t
set_major_version (private_message_t
*this,u_int8_t major_version
)
314 this->major_version
= major_version
;
320 * Implements message_t's get_major_version function.
321 * See #message_s.get_major_version.
323 static u_int8_t
get_major_version (private_message_t
*this)
325 return this->major_version
;
329 * Implements message_t's set_minor_version function.
330 * See #message_s.set_minor_version.
332 static status_t
set_minor_version (private_message_t
*this,u_int8_t minor_version
)
334 this->minor_version
= minor_version
;
340 * Implements message_t's get_minor_version function.
341 * See #message_s.get_minor_version.
343 static u_int8_t
get_minor_version (private_message_t
*this)
345 return this->minor_version
;
349 * Implements message_t's set_exchange_type function.
350 * See #message_s.set_exchange_type.
352 static status_t
set_exchange_type (private_message_t
*this,exchange_type_t exchange_type
)
354 this->exchange_type
= exchange_type
;
360 * Implements message_t's get_exchange_type function.
361 * See #message_s.get_exchange_type.
363 static exchange_type_t
get_exchange_type (private_message_t
*this)
365 return this->exchange_type
;
370 * Implements message_t's set_request function.
371 * See #message_s.set_request.
373 static status_t
set_request (private_message_t
*this,bool request
)
375 this->is_request
= request
;
380 * Implements message_t's get_request function.
381 * See #message_s.get_request.
383 static exchange_type_t
get_request (private_message_t
*this)
385 return this->is_request
;
388 static status_t
add_payload(private_message_t
*this, payload_t
*payload
)
390 payload_t
*last_payload
;
391 if ((this->payloads
->get_count(this->payloads
) > 0) &&
392 (this->payloads
->get_last(this->payloads
,(void **) &last_payload
) != SUCCESS
))
397 if (this->payloads
->insert_last(this->payloads
, payload
) != SUCCESS
)
401 if (this->payloads
->get_count(this->payloads
) == 1)
403 this->first_payload
= payload
->get_type(payload
);
407 last_payload
->set_next_type(last_payload
,payload
->get_type(payload
));
410 this->logger
->log(this->logger
, CONTROL
|MORE
, "added payload of type %s to message",
411 mapping_find(payload_type_m
, payload
->get_type(payload
)));
416 static status_t
set_source(private_message_t
*this, host_t
*host
)
418 if (this->packet
->source
!= NULL
)
420 this->packet
->source
->destroy(this->packet
->source
);
422 this->packet
->source
= host
;
426 static status_t
set_destination(private_message_t
*this, host_t
*host
)
428 if (this->packet
->destination
!= NULL
)
430 this->packet
->destination
->destroy(this->packet
->destination
);
432 this->packet
->destination
= host
;
436 static status_t
get_source(private_message_t
*this, host_t
**host
)
438 *host
= this->packet
->source
;
442 static status_t
get_destination(private_message_t
*this, host_t
**host
)
444 *host
= this->packet
->destination
;
449 static status_t
get_payload_iterator(private_message_t
*this, iterator_t
**iterator
)
451 return this->payloads
->create_iterator(this->payloads
, iterator
, TRUE
);
456 * Implements message_t's generate function.
457 * See #message_s.generate.
459 static status_t
generate(private_message_t
*this, crypter_t
*crypter
, signer_t
* signer
, packet_t
**packet
)
461 generator_t
*generator
;
462 ike_header_t
*ike_header
;
463 payload_t
*payload
, *next_payload
;
464 iterator_t
*iterator
;
468 this->logger
->log(this->logger
, CONTROL
, "generating message, contains %d payloads",
469 this->payloads
->get_count(this->payloads
));
471 if (this->exchange_type
== EXCHANGE_TYPE_UNDEFINED
)
473 this->logger
->log(this->logger
, ERROR
, "exchange type is not defined");
474 return INVALID_STATE
;
477 if (this->packet
->source
== NULL
||
478 this->packet
->destination
== NULL
)
480 this->logger
->log(this->logger
, ERROR
, "source/destination not defined");
481 return INVALID_STATE
;
484 /* build ike header */
485 ike_header
= ike_header_create();
486 if (ike_header
== NULL
)
491 ike_header
->set_exchange_type(ike_header
, this->exchange_type
);
492 ike_header
->set_message_id(ike_header
, this->message_id
);
493 ike_header
->set_response_flag(ike_header
, !this->is_request
);
494 ike_header
->set_initiator_flag(ike_header
, this->ike_sa_id
->is_initiator(this->ike_sa_id
));
495 ike_header
->set_initiator_spi(ike_header
, this->ike_sa_id
->get_initiator_spi(this->ike_sa_id
));
496 ike_header
->set_responder_spi(ike_header
, this->ike_sa_id
->get_responder_spi(this->ike_sa_id
));
498 generator
= generator_create();
499 if (generator
== NULL
)
504 payload
= (payload_t
*)ike_header
;
506 if (this->payloads
->create_iterator(this->payloads
, &iterator
, TRUE
) != SUCCESS
)
508 generator
->destroy(generator
);
509 ike_header
->destroy(ike_header
);
512 /* generate every payload, except last one */
513 while(iterator
->has_next(iterator
))
515 iterator
->current(iterator
, (void**)&next_payload
);
516 payload
->set_next_type(payload
, next_payload
->get_type(next_payload
));
517 status
= generator
->generate_payload(generator
, payload
);
518 if (status
!= SUCCESS
)
520 generator
->destroy(generator
);
521 ike_header
->destroy(ike_header
);
524 payload
= next_payload
;
526 iterator
->destroy(iterator
);
528 /* build last payload */
529 payload
->set_next_type(payload
, NO_PAYLOAD
);
530 /* if it's an encryption payload, build it first */
531 if (payload
->get_type(payload
) == ENCRYPTED
)
533 encryption_payload_t
*encryption_payload
= (encryption_payload_t
*)payload
;
534 encryption_payload
->set_signer(encryption_payload
, signer
);
535 status
= encryption_payload
->encrypt(encryption_payload
, crypter
);
536 if (status
!= SUCCESS
)
538 generator
->destroy(generator
);
539 ike_header
->destroy(ike_header
);
543 status
= generator
->generate_payload(generator
, payload
);
544 if (status
!= SUCCESS
)
546 generator
->destroy(generator
);
547 ike_header
->destroy(ike_header
);
550 ike_header
->destroy(ike_header
);
553 if (this->packet
->data
.ptr
!= NULL
)
555 allocator_free(this->packet
->data
.ptr
);
557 status
= generator
->write_to_chunk(generator
, &(this->packet
->data
));
558 generator
->destroy(generator
);
559 if (status
!= SUCCESS
)
564 /* append integrity checksum if necessary */
565 if (payload
->get_type(payload
) == ENCRYPTED
)
567 encryption_payload_t
*encryption_payload
= (encryption_payload_t
*)payload
;
568 status
= encryption_payload
->build_signature(encryption_payload
, this->packet
->data
);
569 if (status
!= SUCCESS
)
575 /* colen packet for caller */
576 this->packet
->clone(this->packet
, packet
);
578 this->logger
->log(this->logger
, CONTROL
, "message generated successfully");
583 * Implements message_t's parse_header function.
584 * See #message_s.parse_header.
586 static status_t
parse_header(private_message_t
*this)
588 ike_header_t
*ike_header
;
592 this->logger
->log(this->logger
, CONTROL
, "parsing header of message");
594 this->parser
->reset_context(this->parser
);
595 status
= this->parser
->parse_payload(this->parser
,HEADER
,(payload_t
**) &ike_header
);
596 if (status
!= SUCCESS
)
598 this->logger
->log(this->logger
, ERROR
, "Header could not be parsed");
604 status
= ike_header
->payload_interface
.verify(&(ike_header
->payload_interface
));
605 if (status
!= SUCCESS
)
607 this->logger
->log(this->logger
, ERROR
, "Header verification failed");
608 ike_header
->destroy(ike_header
);
612 if (this->ike_sa_id
!= NULL
)
614 this->ike_sa_id
->destroy(this->ike_sa_id
);
617 this->ike_sa_id
= ike_sa_id_create(ike_header
->get_initiator_spi(ike_header
),
618 ike_header
->get_responder_spi(ike_header
),
619 ike_header
->get_initiator_flag(ike_header
));
620 if (this->ike_sa_id
== NULL
)
622 this->logger
->log(this->logger
, ERROR
, "could not create ike_sa_id object");
623 ike_header
->destroy(ike_header
);
626 this->exchange_type
= ike_header
->get_exchange_type(ike_header
);
627 this->message_id
= ike_header
->get_message_id(ike_header
);
628 this->is_request
= (!(ike_header
->get_response_flag(ike_header
)));
629 this->major_version
= ike_header
->get_maj_version(ike_header
);
630 this->minor_version
= ike_header
->get_min_version(ike_header
);
631 this->first_payload
= ike_header
->payload_interface
.get_next_type(&(ike_header
->payload_interface
));
634 this->logger
->log(this->logger
, CONTROL
, "parsing header successfully");
636 ike_header
->destroy(ike_header
);
641 * Implements message_t.parse_body.
643 static status_t
parse_body(private_message_t
*this, crypter_t
*crypter
, signer_t
*signer
)
645 status_t status
= SUCCESS
;
646 payload_type_t current_payload_type
= this->first_payload
;
648 this->logger
->log(this->logger
, CONTROL
, "parsing body of message");
650 while (current_payload_type
!= NO_PAYLOAD
)
652 payload_t
*current_payload
;
654 this->logger
->log(this->logger
, CONTROL
|MORE
, "start parsing payload of type %s",
655 mapping_find(payload_type_m
, current_payload_type
));
657 status
= this->parser
->parse_payload(this->parser
,current_payload_type
,(payload_t
**) ¤t_payload
);
658 if (status
!= SUCCESS
)
660 this->logger
->log(this->logger
, ERROR
, "payload type %s could not be parsed",mapping_find(payload_type_m
,current_payload_type
));
664 status
= current_payload
->verify(current_payload
);
665 if (status
!= SUCCESS
)
667 this->logger
->log(this->logger
, ERROR
, "payload type %s could not be verified",mapping_find(payload_type_m
,current_payload_type
));
668 status
= VERIFY_ERROR
;
672 /* encrypted payload must be decrypted */
673 if (current_payload
->get_type(current_payload
) == ENCRYPTED
)
675 encryption_payload_t
*encryption_payload
= (encryption_payload_t
*)current_payload
;
676 encryption_payload
->set_signer(encryption_payload
, signer
);
677 status
= encryption_payload
->verify_signature(encryption_payload
, this->packet
->data
);
678 if (status
!= SUCCESS
)
680 this->logger
->log(this->logger
, ERROR
, "encryption payload signature invaild");
683 status
= encryption_payload
->decrypt(encryption_payload
, crypter
);
684 if (status
!= SUCCESS
)
686 this->logger
->log(this->logger
, ERROR
, "parsing decrypted encryption payload failed");
691 /* get next payload type */
692 current_payload_type
= current_payload
->get_next_type(current_payload
);
694 status
= this->payloads
->insert_last(this->payloads
,current_payload
);
695 if (status
!= SUCCESS
)
697 this->logger
->log(this->logger
, ERROR
, "%s on adding payload", mapping_find(status_m
, status
));
702 return this->public.verify(&(this->public));
707 * implements message_t.verify
709 static status_t
verify(private_message_t
*this)
711 iterator_t
*iterator
;
714 supported_payload_entry_t
*supported_payloads
;
715 size_t supported_payloads_count
;
717 this->logger
->log(this->logger
, CONTROL
|MORE
, "verifying message");
719 status
= this->get_supported_payloads(this, &supported_payloads
, &supported_payloads_count
);
720 if (status
!= SUCCESS
)
722 this->logger
->log(this->logger
, ERROR
, "could not get supported payloads: %s");
726 status
= this->payloads
->create_iterator(this->payloads
,&iterator
,TRUE
);
727 if (status
!= SUCCESS
)
729 this->logger
->log(this->logger
, ERROR
, "Could not create iterator to check supported payloads");
733 /* check for payloads with wrong count*/
734 for (i
= 0; i
< supported_payloads_count
;i
++)
736 size_t min_occurence
= supported_payloads
[i
].min_occurence
;
737 size_t max_occurence
= supported_payloads
[i
].max_occurence
;
738 payload_type_t payload_type
= supported_payloads
[i
].payload_type
;
739 size_t found_payloads
= 0;
741 iterator
->reset(iterator
);
743 while(iterator
->has_next(iterator
))
745 payload_t
*current_payload
;
746 status
= iterator
->current(iterator
,(void **)¤t_payload
);
747 if (status
!= SUCCESS
)
749 this->logger
->log(this->logger
, ERROR
, "Could not get payload from internal list");
750 iterator
->destroy(iterator
);
753 if (current_payload
->get_type(current_payload
) == payload_type
)
756 if (found_payloads
> max_occurence
)
758 this->logger
->log(this->logger
, ERROR
, "Payload of type %s more than %d times (%d) occured in current message",
759 mapping_find(payload_type_m
,current_payload
->get_type(current_payload
)),max_occurence
,found_payloads
);
760 iterator
->destroy(iterator
);
761 return NOT_SUPPORTED
;
765 if (found_payloads
< min_occurence
)
767 this->logger
->log(this->logger
, ERROR
, "Payload of type %s not occured %d times",
768 mapping_find(payload_type_m
,payload_type
),min_occurence
);
769 iterator
->destroy(iterator
);
770 return NOT_SUPPORTED
;
773 iterator
->destroy(iterator
);
780 * Implements message_t's destroy function.
781 * See #message_s.destroy.
783 static status_t
destroy (private_message_t
*this)
785 iterator_t
*iterator
;
787 this->packet
->destroy(this->packet
);
789 if (this->ike_sa_id
!= NULL
)
791 this->ike_sa_id
->destroy(this->ike_sa_id
);
794 this->payloads
->create_iterator(this->payloads
, &iterator
, TRUE
);
795 while (iterator
->has_next(iterator
))
798 iterator
->current(iterator
, (void**)&payload
);
799 this->logger
->log(this->logger
, CONTROL
|MOST
, "Destroying payload of type %s",
800 mapping_find(payload_type_m
, payload
->get_type(payload
)));
801 payload
->destroy(payload
);
803 iterator
->destroy(iterator
);
804 this->payloads
->destroy(this->payloads
);
805 this->parser
->destroy(this->parser
);
806 global_logger_manager
->destroy_logger(global_logger_manager
, this->logger
);
808 allocator_free(this);
813 * Described in Header-File
815 message_t
*message_create_from_packet(packet_t
*packet
)
817 private_message_t
*this = allocator_alloc_thing(private_message_t
);
823 /* public functions */
824 this->public.set_major_version
= (status_t(*)(message_t
*, u_int8_t
))set_major_version
;
825 this->public.get_major_version
= (u_int8_t(*)(message_t
*))get_major_version
;
826 this->public.set_minor_version
= (status_t(*)(message_t
*, u_int8_t
))set_minor_version
;
827 this->public.get_minor_version
= (u_int8_t(*)(message_t
*))get_minor_version
;
828 this->public.set_message_id
= (status_t(*)(message_t
*, u_int32_t
))set_message_id
;
829 this->public.get_message_id
= (u_int32_t(*)(message_t
*))get_message_id
;
830 this->public.get_responder_spi
= (u_int64_t(*)(message_t
*))get_responder_spi
;
831 this->public.set_ike_sa_id
= (status_t(*)(message_t
*, ike_sa_id_t
*))set_ike_sa_id
;
832 this->public.get_ike_sa_id
= (status_t(*)(message_t
*, ike_sa_id_t
**))get_ike_sa_id
;
833 this->public.set_exchange_type
= (status_t(*)(message_t
*, exchange_type_t
))set_exchange_type
;
834 this->public.get_exchange_type
= (exchange_type_t(*)(message_t
*))get_exchange_type
;
835 this->public.set_request
= (status_t(*)(message_t
*, bool))set_request
;
836 this->public.get_request
= (bool(*)(message_t
*))get_request
;
837 this->public.add_payload
= (status_t(*)(message_t
*,payload_t
*))add_payload
;
838 this->public.generate
= (status_t (*) (message_t
*,crypter_t
*,signer_t
*,packet_t
**)) generate
;
839 this->public.set_source
= (status_t (*) (message_t
*,host_t
*)) set_source
;
840 this->public.get_source
= (status_t (*) (message_t
*,host_t
**)) get_source
;
841 this->public.set_destination
= (status_t (*) (message_t
*,host_t
*)) set_destination
;
842 this->public.get_destination
= (status_t (*) (message_t
*,host_t
**)) get_destination
;
843 this->public.get_payload_iterator
= (status_t (*) (message_t
*, iterator_t
**)) get_payload_iterator
;
844 this->public.parse_header
= (status_t (*) (message_t
*)) parse_header
;
845 this->public.parse_body
= (status_t (*) (message_t
*,crypter_t
*,signer_t
*)) parse_body
;
846 this->public.verify
= (status_t (*) (message_t
*)) verify
;
847 this->public.destroy
= (status_t(*)(message_t
*))destroy
;
850 this->exchange_type
= EXCHANGE_TYPE_UNDEFINED
;
851 this->is_request
= TRUE
;
852 this->ike_sa_id
= NULL
;
853 this->first_payload
= NO_PAYLOAD
;
854 this->message_id
= 0;
856 /* private functions */
857 this->get_supported_payloads
= get_supported_payloads
;
862 packet
= packet_create();
866 allocator_free(this);
869 this->packet
= packet
;
870 this->payloads
= linked_list_create();
871 if (this->payloads
== NULL
)
873 allocator_free(this);
877 /* parser is created from data of packet */
878 this->parser
= parser_create(this->packet
->data
);
879 if (this->parser
== NULL
)
881 this->payloads
->destroy(this->payloads
);
882 allocator_free(this);
886 this->logger
= global_logger_manager
->create_logger(global_logger_manager
, MESSAGE
, NULL
);
887 if (this->logger
== NULL
)
889 this->parser
->destroy(this->parser
);
890 this->payloads
->destroy(this->payloads
);
891 allocator_free(this);
895 return (&this->public);
899 * Described in Header-File
901 message_t
*message_create()
903 return message_create_from_packet(NULL
);