4 * @brief Implementation of ike_auth_t transaction.
9 * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
10 * Copyright (C) 2005-2006 Martin Willi
11 * Copyright (C) 2005 Jan Hutter
12 * Hochschule fuer Technik Rapperswil
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30 #include <encoding/payloads/sa_payload.h>
31 #include <encoding/payloads/id_payload.h>
32 #include <encoding/payloads/cert_payload.h>
33 #include <encoding/payloads/certreq_payload.h>
34 #include <encoding/payloads/auth_payload.h>
35 #include <encoding/payloads/ts_payload.h>
36 #include <sa/authenticator.h>
37 #include <sa/child_sa.h>
40 typedef struct private_ike_auth_t private_ike_auth_t
;
43 * Private members of a ike_auth_t object..
45 struct private_ike_auth_t
{
48 * Public methods and transaction_t interface.
58 * Message sent by our peer, if already generated
63 * Message ID this transaction uses
68 * Times we did send the request
73 * initiator chosen nonce
78 * responder chosen nonce
83 * encoded request message of ike_sa_init transaction
88 * encoded response message of ike_sa_init transaction
90 chunk_t init_response
;
93 * connection definition used for IKE_SA setup
95 connection_t
*connection
;
98 * policy definition used CHILD_SA creation
103 * Negotiated proposal used for CHILD_SA
105 proposal_t
*proposal
;
108 * Negotiated traffic selectors for initiator
113 * Negotiated traffic selectors for responder
118 * CHILD_SA created along with IKE_AUTH
120 child_sa_t
*child_sa
;
123 * did other peer create a CHILD_SA?
128 * reqid to use for CHILD_SA setup
139 * Implementation of transaction_t.get_message_id.
141 static u_int32_t
get_message_id(private_ike_auth_t
*this)
143 return this->message_id
;
147 * Implementation of transaction_t.requested.
149 static u_int32_t
requested(private_ike_auth_t
*this)
151 return this->requested
++;
155 * Implementation of transaction_t.set_config.
157 static void set_config(private_ike_auth_t
*this,
158 connection_t
*connection
, policy_t
*policy
)
160 this->connection
= connection
;
161 this->policy
= policy
;
165 * Implementation of transaction_t.set_reqid.
167 static void set_reqid(private_ike_auth_t
*this, u_int32_t reqid
)
173 * Implementation of transaction_t.set_nonces.
175 static void set_nonces(private_ike_auth_t
*this, chunk_t nonce_i
, chunk_t nonce_r
)
177 this->nonce_i
= nonce_i
;
178 this->nonce_r
= nonce_r
;
182 * Implementation of transaction_t.set_init_messages.
184 static void set_init_messages(private_ike_auth_t
*this, chunk_t init_request
, chunk_t init_response
)
186 this->init_request
= init_request
;
187 this->init_response
= init_response
;
191 * destroy a list of traffic selectors
193 static void destroy_ts_list(linked_list_t
*list
)
197 traffic_selector_t
*ts
;
199 while (list
->remove_last(list
, (void**)&ts
) == SUCCESS
)
208 * destroy a list of proposals
210 static void destroy_proposal_list(linked_list_t
*list
)
212 proposal_t
*proposal
;
214 while (list
->remove_last(list
, (void**)&proposal
) == SUCCESS
)
216 proposal
->destroy(proposal
);
222 * Implementation of transaction_t.get_request.
224 static status_t
get_request(private_ike_auth_t
*this, message_t
**result
)
228 identification_t
*my_id
, *other_id
;
229 id_payload_t
*my_id_payload
;
231 /* check if we already have built a message (retransmission) */
234 *result
= this->message
;
238 me
= this->ike_sa
->get_my_host(this->ike_sa
);
239 other
= this->ike_sa
->get_other_host(this->ike_sa
);
240 my_id
= this->policy
->get_my_id(this->policy
);
241 other_id
= this->policy
->get_other_id(this->policy
);
243 /* build the request */
244 request
= message_create();
245 request
->set_source(request
, me
->clone(me
));
246 request
->set_destination(request
, other
->clone(other
));
247 request
->set_exchange_type(request
, IKE_AUTH
);
248 request
->set_request(request
, TRUE
);
249 request
->set_ike_sa_id(request
, this->ike_sa
->get_id(this->ike_sa
));
250 /* apply for caller */
252 /* store for retransmission */
253 this->message
= request
;
255 { /* build ID payload */
256 my_id_payload
= id_payload_create_from_identification(TRUE
, my_id
);
257 request
->add_payload(request
, (payload_t
*)my_id_payload
);
260 { /* TODO: build certreq payload */
264 if (this->connection
->get_cert_policy(this->connection
) != CERT_NEVER_SEND
)
265 { /* build certificate payload. TODO: Handle certreq from init_ike_sa. */
267 cert_payload_t
*cert_payload
;
269 cert
= charon
->credentials
->get_certificate(charon
->credentials
, my_id
);
272 cert_payload
= cert_payload_create_from_x509(cert
);
273 request
->add_payload(request
, (payload_t
*)cert_payload
);
277 this->logger
->log(this->logger
, ERROR
,
278 "could not find my certificate, certificate payload omitted");
282 { /* build IDr payload, if other_id defined */
283 id_payload_t
*id_payload
;
284 if (!other_id
->contains_wildcards(other_id
))
286 id_payload
= id_payload_create_from_identification(FALSE
, other_id
);
287 request
->add_payload(request
, (payload_t
*)id_payload
);
291 { /* build auth payload */
292 authenticator_t
*authenticator
;
293 auth_payload_t
*auth_payload
;
294 auth_method_t auth_method
;
297 auth_method
= this->connection
->get_auth_method(this->connection
);
298 authenticator
= authenticator_create(this->ike_sa
, auth_method
);
299 status
= authenticator
->compute_auth_data(authenticator
, &auth_payload
,
300 this->init_request
, this->nonce_r
, my_id_payload
, TRUE
);
301 authenticator
->destroy(authenticator
);
302 if (status
!= SUCCESS
)
304 this->logger
->log(this->logger
, AUDIT
,
305 "could not generate AUTH data, deleting IKE_SA");
308 request
->add_payload(request
, (payload_t
*)auth_payload
);
311 { /* build SA payload for CHILD_SA */
312 linked_list_t
*proposal_list
;
313 sa_payload_t
*sa_payload
;
314 u_int32_t soft_lifetime
, hard_lifetime
;
317 proposal_list
= this->policy
->get_proposals(this->policy
);
318 soft_lifetime
= this->policy
->get_soft_lifetime(this->policy
);
319 hard_lifetime
= this->policy
->get_hard_lifetime(this->policy
);
320 enable_natt
= this->ike_sa
->is_natt_enabled(this->ike_sa
);
321 this->child_sa
= child_sa_create(this->reqid
, me
, other
, my_id
, other_id
,
322 soft_lifetime
, hard_lifetime
,
323 this->policy
->get_updown(this->policy
),
325 this->child_sa
->set_name(this->child_sa
, this->policy
->get_name(this->policy
));
326 if (this->child_sa
->alloc(this->child_sa
, proposal_list
) != SUCCESS
)
328 this->logger
->log(this->logger
, ERROR
,
329 "could not install CHILD_SA, deleting IKE_SA");
332 sa_payload
= sa_payload_create_from_proposal_list(proposal_list
);
333 destroy_proposal_list(proposal_list
);
334 request
->add_payload(request
, (payload_t
*)sa_payload
);
337 { /* build TSi payload */
338 linked_list_t
*ts_list
;
339 ts_payload_t
*ts_payload
;
341 ts_list
= this->policy
->get_my_traffic_selectors(this->policy
, me
);
342 ts_payload
= ts_payload_create_from_traffic_selectors(TRUE
, ts_list
);
343 destroy_ts_list(ts_list
);
345 request
->add_payload(request
, (payload_t
*)ts_payload
);
348 { /* build TSr payload */
349 linked_list_t
*ts_list
;
350 ts_payload_t
*ts_payload
;
352 ts_list
= this->policy
->get_other_traffic_selectors(this->policy
, other
);
353 ts_payload
= ts_payload_create_from_traffic_selectors(FALSE
, ts_list
);
354 destroy_ts_list(ts_list
);
356 request
->add_payload(request
, (payload_t
*)ts_payload
);
359 this->message_id
= this->ike_sa
->get_next_message_id(this->ike_sa
);
360 request
->set_message_id(request
, this->message_id
);
365 * Handle all kind of notifies
367 static status_t
process_notifies(private_ike_auth_t
*this, notify_payload_t
*notify_payload
)
369 notify_type_t notify_type
= notify_payload
->get_notify_type(notify_payload
);
371 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "process notify type %s",
372 mapping_find(notify_type_m
, notify_type
));
376 /* these notifies are not critical. no child_sa is built, but IKE stays alive */
377 case SINGLE_PAIR_REQUIRED
:
379 this->logger
->log(this->logger
, AUDIT
,
380 "received a SINGLE_PAIR_REQUIRED notify");
381 this->build_child
= FALSE
;
384 case TS_UNACCEPTABLE
:
386 this->logger
->log(this->logger
, CONTROL
,
387 "received TS_UNACCEPTABLE notify");
388 this->build_child
= FALSE
;
391 case NO_PROPOSAL_CHOSEN
:
393 this->logger
->log(this->logger
, CONTROL
,
394 "received NO_PROPOSAL_CHOSEN notify");
395 this->build_child
= FALSE
;
400 if (notify_type
< 16383)
402 this->logger
->log(this->logger
, AUDIT
,
403 "received %s notify error (%d), deleting IKE_SA",
404 mapping_find(notify_type_m
, notify_type
),
410 this->logger
->log(this->logger
, CONTROL
,
411 "received %s notify (%d), ignored",
412 mapping_find(notify_type_m
, notify_type
),
421 * Build a notify message.
423 static void build_notify(notify_type_t type
, message_t
*message
, bool flush_message
)
425 notify_payload_t
*notify
;
430 iterator_t
*iterator
= message
->get_payload_iterator(message
);
431 while (iterator
->iterate(iterator
, (void**)&payload
))
433 payload
->destroy(payload
);
434 iterator
->remove(iterator
);
436 iterator
->destroy(iterator
);
439 notify
= notify_payload_create();
440 notify
->set_notify_type(notify
, type
);
441 message
->add_payload(message
, (payload_t
*)notify
);
445 * Import a certificate from a cert payload
447 static void import_certificate(private_ike_auth_t
*this, cert_payload_t
*cert_payload
)
451 cert_encoding_t encoding
;
453 encoding
= cert_payload
->get_cert_encoding(cert_payload
);
454 if (encoding
!= CERT_X509_SIGNATURE
)
456 this->logger
->log(this->logger
, ERROR
,
457 "certificate payload %s not supported, ignored",
458 enum_name(&cert_encoding_names
, encoding
));
461 cert
= x509_create_from_chunk(cert_payload
->get_data_clone(cert_payload
));
464 if (charon
->credentials
->verify(charon
->credentials
, cert
, &found
))
466 this->logger
->log(this->logger
, CONTROL
|LEVEL1
,
467 "received end entity certificate is trusted, added to store");
470 charon
->credentials
->add_end_certificate(charon
->credentials
, cert
);
479 this->logger
->log(this->logger
, CONTROL
,
480 "received end entity certificate is not trusted, discarded");
486 this->logger
->log(this->logger
, CONTROL
,
487 "parsing of received certificate failed, discarded");
492 * Install a CHILD_SA for usage
494 static status_t
install_child_sa(private_ike_auth_t
*this, bool initiator
)
496 prf_plus_t
*prf_plus
;
500 seed
= chunk_alloc(this->nonce_i
.len
+ this->nonce_r
.len
);
501 memcpy(seed
.ptr
, this->nonce_i
.ptr
, this->nonce_i
.len
);
502 memcpy(seed
.ptr
+ this->nonce_i
.len
, this->nonce_r
.ptr
, this->nonce_r
.len
);
503 prf_plus
= prf_plus_create(this->ike_sa
->get_child_prf(this->ike_sa
), seed
);
508 status
= this->child_sa
->update(this->child_sa
, this->proposal
, prf_plus
);
512 status
= this->child_sa
->add(this->child_sa
, this->proposal
, prf_plus
);
514 prf_plus
->destroy(prf_plus
);
515 if (status
!= SUCCESS
)
521 status
= this->child_sa
->add_policies(this->child_sa
, this->tsi
, this->tsr
);
525 status
= this->child_sa
->add_policies(this->child_sa
, this->tsr
, this->tsi
);
527 if (status
!= SUCCESS
)
532 /* add to IKE_SA, and remove from transaction */
533 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLED
);
534 this->ike_sa
->add_child_sa(this->ike_sa
, this->child_sa
);
535 this->child_sa
= NULL
;
540 * Implementation of transaction_t.get_response.
542 static status_t
get_response(private_ike_auth_t
*this, message_t
*request
,
543 message_t
**result
, transaction_t
**next
)
546 identification_t
*my_id
, *other_id
;
549 iterator_t
*payloads
;
550 id_payload_t
*idi_request
= NULL
;
551 id_payload_t
*idr_request
= NULL
;
552 auth_payload_t
*auth_request
= NULL
;
553 cert_payload_t
*cert_request
= NULL
;
554 sa_payload_t
*sa_request
= NULL
;
555 ts_payload_t
*tsi_request
= NULL
;
556 ts_payload_t
*tsr_request
= NULL
;
557 id_payload_t
*idr_response
;
559 /* check if we already have built a response (retransmission) */
562 *result
= this->message
;
566 me
= this->ike_sa
->get_my_host(this->ike_sa
);
567 other
= this->ike_sa
->get_other_host(this->ike_sa
);
568 this->message_id
= request
->get_message_id(request
);
570 /* set up response */
571 response
= message_create();
572 response
->set_source(response
, me
->clone(me
));
573 response
->set_destination(response
, other
->clone(other
));
574 response
->set_exchange_type(response
, IKE_AUTH
);
575 response
->set_request(response
, FALSE
);
576 response
->set_message_id(response
, this->message_id
);
577 response
->set_ike_sa_id(response
, this->ike_sa
->get_id(this->ike_sa
));
578 this->message
= response
;
581 /* check message type */
582 if (request
->get_exchange_type(request
) != IKE_AUTH
)
584 this->logger
->log(this->logger
, ERROR
,
585 "IKE_AUTH response of invalid type, deleting IKE_SA");
589 /* Iterate over all payloads. */
590 payloads
= request
->get_payload_iterator(request
);
591 while (payloads
->has_next(payloads
))
594 payloads
->current(payloads
, (void**)&payload
);
595 switch (payload
->get_type(payload
))
598 idi_request
= (id_payload_t
*)payload
;
601 idr_request
= (id_payload_t
*)payload
;
604 auth_request
= (auth_payload_t
*)payload
;
607 cert_request
= (cert_payload_t
*)payload
;
609 case SECURITY_ASSOCIATION
:
610 sa_request
= (sa_payload_t
*)payload
;
612 case TRAFFIC_SELECTOR_INITIATOR
:
613 tsi_request
= (ts_payload_t
*)payload
;
615 case TRAFFIC_SELECTOR_RESPONDER
:
616 tsr_request
= (ts_payload_t
*)payload
;
620 status
= process_notifies(this, (notify_payload_t
*)payload
);
621 if (status
== FAILED
)
623 payloads
->destroy(payloads
);
624 /* we return SUCCESS, returned FAILED means do next transaction */
627 if (status
== DESTROY_ME
)
629 payloads
->destroy(payloads
);
636 this->logger
->log(this->logger
, ERROR
, "ignoring %s payload (%d)",
637 mapping_find(payload_type_m
, payload
->get_type(payload
)),
638 payload
->get_type(payload
));
643 payloads
->destroy(payloads
);
645 /* check if we have all payloads */
646 if (!(idi_request
&& auth_request
&& sa_request
&& tsi_request
&& tsr_request
))
648 build_notify(INVALID_SYNTAX
, response
, TRUE
);
649 this->logger
->log(this->logger
, AUDIT
,
650 "request message incomplete, deleting IKE_SA");
654 { /* process ID payload */
655 other_id
= idi_request
->get_identification(idi_request
);
658 my_id
= idr_request
->get_identification(idr_request
);
662 my_id
= identification_create_from_encoding(ID_ANY
, CHUNK_INITIALIZER
);
666 { /* get a policy and process traffic selectors */
667 linked_list_t
*my_ts
, *other_ts
;
669 my_ts
= tsr_request
->get_traffic_selectors(tsr_request
);
670 other_ts
= tsi_request
->get_traffic_selectors(tsi_request
);
672 this->policy
= charon
->policies
->get_policy(charon
->policies
,
678 this->tsr
= this->policy
->select_my_traffic_selectors(this->policy
, my_ts
, me
);
679 this->tsi
= this->policy
->select_other_traffic_selectors(this->policy
, other_ts
, other
);
681 destroy_ts_list(my_ts
);
682 destroy_ts_list(other_ts
);
684 /* TODO: We should check somehow if we have a policy, but with other
685 * traffic selectors. Then we would create a IKE_SA without a CHILD_SA. */
686 if (this->policy
== NULL
)
688 this->logger
->log(this->logger
, AUDIT
,
689 "no acceptable policy for IDs %s - %s found, deleting IKE_SA",
690 my_id
->get_string(my_id
), other_id
->get_string(other_id
));
691 my_id
->destroy(my_id
);
692 other_id
->destroy(other_id
);
693 build_notify(AUTHENTICATION_FAILED
, response
, TRUE
);
696 my_id
->destroy(my_id
);
698 /* get my id from policy, which must contain a fully qualified valid id */
699 my_id
= this->policy
->get_my_id(this->policy
);
700 this->ike_sa
->set_my_id(this->ike_sa
, my_id
->clone(my_id
));
701 this->ike_sa
->set_other_id(this->ike_sa
, other_id
);
703 idr_response
= id_payload_create_from_identification(FALSE
, my_id
);
704 response
->add_payload(response
, (payload_t
*)idr_response
);
707 if (this->connection
->get_cert_policy(this->connection
) != CERT_NEVER_SEND
)
708 { /* build certificate payload */
710 cert_payload_t
*cert_payload
;
712 cert
= charon
->credentials
->get_certificate(charon
->credentials
, my_id
);
715 this->logger
->log(this->logger
, ERROR
,
716 "could not find my certificate, cert payload omitted");
718 cert_payload
= cert_payload_create_from_x509(cert
);
719 response
->add_payload(response
, (payload_t
*)cert_payload
);
723 { /* process certificate payload */
724 import_certificate(this, cert_request
);
727 { /* process auth payload */
728 authenticator_t
*authenticator
;
729 auth_payload_t
*auth_response
;
730 auth_method_t auth_method
;
733 auth_method
= this->connection
->get_auth_method(this->connection
);
734 authenticator
= authenticator_create(this->ike_sa
, auth_method
);
735 status
= authenticator
->verify_auth_data(authenticator
, auth_request
,
737 this->nonce_r
, idi_request
,
739 if (status
!= SUCCESS
)
741 this->logger
->log(this->logger
, AUDIT
,
742 "authentication failed, deleting IKE_SA");
743 build_notify(AUTHENTICATION_FAILED
, response
, TRUE
);
744 authenticator
->destroy(authenticator
);
747 status
= authenticator
->compute_auth_data(authenticator
, &auth_response
,
749 this->nonce_i
, idr_response
,
751 authenticator
->destroy(authenticator
);
752 if (status
!= SUCCESS
)
754 this->logger
->log(this->logger
, AUDIT
,
755 "authentication data generation failed, deleting IKE_SA");
756 build_notify(AUTHENTICATION_FAILED
, response
, TRUE
);
759 response
->add_payload(response
, (payload_t
*)auth_response
);
762 { /* process SA payload */
763 linked_list_t
*proposal_list
;
764 sa_payload_t
*sa_response
;
765 ts_payload_t
*ts_response
;
767 u_int32_t soft_lifetime
, hard_lifetime
;
770 sa_response
= sa_payload_create();
772 /* get proposals from request, and select one with ours */
773 proposal_list
= sa_request
->get_proposals(sa_request
);
774 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "selecting proposals:");
775 this->proposal
= this->policy
->select_proposal(this->policy
, proposal_list
);
776 destroy_proposal_list(proposal_list
);
778 /* do we have a proposal? */
779 if (this->proposal
== NULL
)
781 this->logger
->log(this->logger
, AUDIT
,
782 "CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
783 build_notify(NO_PROPOSAL_CHOSEN
, response
, FALSE
);
785 /* do we have traffic selectors? */
786 else if (this->tsi
->get_count(this->tsi
) == 0 || this->tsr
->get_count(this->tsr
) == 0)
788 this->logger
->log(this->logger
, AUDIT
,
789 "CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
790 build_notify(TS_UNACCEPTABLE
, response
, FALSE
);
794 /* create child sa */
795 soft_lifetime
= this->policy
->get_soft_lifetime(this->policy
);
796 hard_lifetime
= this->policy
->get_hard_lifetime(this->policy
);
797 use_natt
= this->ike_sa
->is_natt_enabled(this->ike_sa
);
798 this->child_sa
= child_sa_create(this->reqid
, me
, other
, my_id
, other_id
,
799 soft_lifetime
, hard_lifetime
,
800 this->policy
->get_updown(this->policy
),
802 this->child_sa
->set_name(this->child_sa
, this->policy
->get_name(this->policy
));
803 if (install_child_sa(this, FALSE
) != SUCCESS
)
805 this->logger
->log(this->logger
, ERROR
,
806 "installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
807 build_notify(NO_PROPOSAL_CHOSEN
, response
, FALSE
);
809 /* add proposal to sa payload */
810 sa_response
->add_proposal(sa_response
, this->proposal
);
812 response
->add_payload(response
, (payload_t
*)sa_response
);
814 /* add ts payload after sa payload */
815 ts_response
= ts_payload_create_from_traffic_selectors(TRUE
, this->tsi
);
816 response
->add_payload(response
, (payload_t
*)ts_response
);
817 ts_response
= ts_payload_create_from_traffic_selectors(FALSE
, this->tsr
);
818 response
->add_payload(response
, (payload_t
*)ts_response
);
820 /* set established state */
821 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
827 * Implementation of transaction_t.conclude
829 static status_t
conclude(private_ike_auth_t
*this, message_t
*response
,
830 transaction_t
**transaction
)
832 iterator_t
*payloads
;
834 identification_t
*other_id
;
835 ts_payload_t
*tsi_payload
= NULL
;
836 ts_payload_t
*tsr_payload
= NULL
;
837 id_payload_t
*idr_payload
= NULL
;
838 cert_payload_t
*cert_payload
= NULL
;
839 auth_payload_t
*auth_payload
= NULL
;
840 sa_payload_t
*sa_payload
= NULL
;
843 /* check message type */
844 if (response
->get_exchange_type(response
) != IKE_AUTH
)
846 this->logger
->log(this->logger
, ERROR
,
847 "IKE_AUTH response of invalid type, deleting IKE_SA");
851 me
= this->ike_sa
->get_my_host(this->ike_sa
);
852 other
= this->ike_sa
->get_other_host(this->ike_sa
);
854 /* Iterate over all payloads to collect them */
855 payloads
= response
->get_payload_iterator(response
);
856 while (payloads
->has_next(payloads
))
859 payloads
->current(payloads
, (void**)&payload
);
861 switch (payload
->get_type(payload
))
864 idr_payload
= (id_payload_t
*)payload
;
867 auth_payload
= (auth_payload_t
*)payload
;
870 cert_payload
= (cert_payload_t
*)payload
;
872 case SECURITY_ASSOCIATION
:
873 sa_payload
= (sa_payload_t
*)payload
;
875 case TRAFFIC_SELECTOR_INITIATOR
:
876 tsi_payload
= (ts_payload_t
*)payload
;
878 case TRAFFIC_SELECTOR_RESPONDER
:
879 tsr_payload
= (ts_payload_t
*)payload
;
883 status
= process_notifies(this, (notify_payload_t
*)payload
);
884 if (status
== FAILED
)
886 payloads
->destroy(payloads
);
887 /* we return SUCCESS, returned FAILED means do next transaction */
890 if (status
== DESTROY_ME
)
892 payloads
->destroy(payloads
);
899 this->logger
->log(this->logger
, CONTROL
, "ignoring payload %s (%d)",
900 mapping_find(payload_type_m
, payload
->get_type(payload
)),
901 payload
->get_type(payload
));
906 payloads
->destroy(payloads
);
908 if (!(idr_payload
&& auth_payload
&& sa_payload
&& tsi_payload
&& tsr_payload
))
910 this->logger
->log(this->logger
, AUDIT
, "response message incomplete, deleting IKE_SA");
914 { /* process idr payload */
915 identification_t
*configured_other_id
;
918 other_id
= idr_payload
->get_identification(idr_payload
);
919 configured_other_id
= this->policy
->get_other_id(this->policy
);
921 if (!other_id
->matches(other_id
, configured_other_id
, &wildcards
))
923 other_id
->destroy(other_id
);
924 this->logger
->log(this->logger
, AUDIT
,
925 "other peer uses unacceptable ID (%s, excepted %s), deleting IKE_SA",
926 other_id
->get_string(other_id
),
927 configured_other_id
->get_string(configured_other_id
));
930 /* update other ID. It was already set, but may contain wildcards */
931 this->ike_sa
->set_other_id(this->ike_sa
, other_id
);
935 { /* process cert payload */
936 import_certificate(this, cert_payload
);
939 { /* authenticate peer */
940 authenticator_t
*authenticator
;
941 auth_method_t auth_method
;
944 auth_method
= this->connection
->get_auth_method(this->connection
);
945 authenticator
= authenticator_create(this->ike_sa
, auth_method
);
946 status
= authenticator
->verify_auth_data(authenticator
, auth_payload
,
948 this->nonce_i
, idr_payload
,
950 authenticator
->destroy(authenticator
);
951 if (status
!= SUCCESS
)
953 this->logger
->log(this->logger
, AUDIT
, "authentication failed, deleting IKE_SA");
958 { /* process traffic selectors for us */
959 linked_list_t
*ts_received
= tsi_payload
->get_traffic_selectors(tsi_payload
);
960 this->tsi
= this->policy
->select_my_traffic_selectors(this->policy
, ts_received
, me
);
961 destroy_ts_list(ts_received
);
964 { /* process traffic selectors for other */
965 linked_list_t
*ts_received
= tsr_payload
->get_traffic_selectors(tsr_payload
);
966 this->tsr
= this->policy
->select_other_traffic_selectors(this->policy
, ts_received
, other
);
967 destroy_ts_list(ts_received
);
970 { /* process sa payload */
971 linked_list_t
*proposal_list
;
973 proposal_list
= sa_payload
->get_proposals(sa_payload
);
974 /* we have to re-check here if other's selection is valid */
975 this->proposal
= this->policy
->select_proposal(this->policy
, proposal_list
);
976 destroy_proposal_list(proposal_list
);
978 /* everything fine to create CHILD? */
979 if (this->proposal
== NULL
||
980 this->tsi
->get_count(this->tsi
) == 0 ||
981 this->tsr
->get_count(this->tsr
) == 0 ||
984 this->logger
->log(this->logger
, AUDIT
,
985 "CHILD_SA creation failed");
989 if (install_child_sa(this, TRUE
) != SUCCESS
)
991 this->logger
->log(this->logger
, ERROR
,
992 "installing CHILD_SA failed, no CHILD_SA built");
997 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
1002 * implements transaction_t.destroy
1004 static void destroy(private_ike_auth_t
*this)
1006 DESTROY_IF(this->message
);
1007 DESTROY_IF(this->proposal
);
1008 DESTROY_IF(this->child_sa
);
1009 DESTROY_IF(this->policy
);
1010 DESTROY_IF(this->connection
);
1011 destroy_ts_list(this->tsi
);
1012 destroy_ts_list(this->tsr
);
1013 chunk_free(&this->nonce_i
);
1014 chunk_free(&this->nonce_r
);
1015 chunk_free(&this->init_request
);
1016 chunk_free(&this->init_response
);
1021 * Described in header.
1023 ike_auth_t
*ike_auth_create(ike_sa_t
*ike_sa
)
1025 private_ike_auth_t
*this = malloc_thing(private_ike_auth_t
);
1027 /* transaction interface functions */
1028 this->public.transaction
.get_request
= (status_t(*)(transaction_t
*,message_t
**))get_request
;
1029 this->public.transaction
.get_response
= (status_t(*)(transaction_t
*,message_t
*,message_t
**,transaction_t
**))get_response
;
1030 this->public.transaction
.conclude
= (status_t(*)(transaction_t
*,message_t
*,transaction_t
**))conclude
;
1031 this->public.transaction
.get_message_id
= (u_int32_t(*)(transaction_t
*))get_message_id
;
1032 this->public.transaction
.requested
= (u_int32_t(*)(transaction_t
*))requested
;
1033 this->public.transaction
.destroy
= (void(*)(transaction_t
*))destroy
;
1035 /* public functions */
1036 this->public.set_config
= (void(*)(ike_auth_t
*,connection_t
*,policy_t
*))set_config
;
1037 this->public.set_reqid
= (void(*)(ike_auth_t
*,u_int32_t
))set_reqid
;
1038 this->public.set_nonces
= (void(*)(ike_auth_t
*,chunk_t
,chunk_t
))set_nonces
;
1039 this->public.set_init_messages
= (void(*)(ike_auth_t
*,chunk_t
,chunk_t
))set_init_messages
;
1042 this->ike_sa
= ike_sa
;
1043 this->message_id
= 0;
1044 this->message
= NULL
;
1045 this->requested
= 0;
1046 this->nonce_i
= CHUNK_INITIALIZER
;
1047 this->nonce_r
= CHUNK_INITIALIZER
;
1048 this->init_request
= CHUNK_INITIALIZER
;
1049 this->init_response
= CHUNK_INITIALIZER
;
1050 this->child_sa
= NULL
;
1051 this->proposal
= NULL
;
1054 this->build_child
= TRUE
;
1056 this->logger
= logger_manager
->get_logger(logger_manager
, IKE_SA
);
1058 return &this->public;