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
));
463 if (charon
->credentials
->verify(charon
->credentials
, cert
, &found
))
465 this->logger
->log(this->logger
, CONTROL
|LEVEL1
,
466 "received end entity certificate is trusted, added to store");
473 cert
= charon
->credentials
->add_end_certificate(charon
->credentials
, cert
);
479 this->logger
->log(this->logger
, CONTROL
,
480 "received end entity certificate is not trusted, discarded");
485 * Install a CHILD_SA for usage
487 static status_t
install_child_sa(private_ike_auth_t
*this, bool initiator
)
489 prf_plus_t
*prf_plus
;
493 seed
= chunk_alloc(this->nonce_i
.len
+ this->nonce_r
.len
);
494 memcpy(seed
.ptr
, this->nonce_i
.ptr
, this->nonce_i
.len
);
495 memcpy(seed
.ptr
+ this->nonce_i
.len
, this->nonce_r
.ptr
, this->nonce_r
.len
);
496 prf_plus
= prf_plus_create(this->ike_sa
->get_child_prf(this->ike_sa
), seed
);
501 status
= this->child_sa
->update(this->child_sa
, this->proposal
, prf_plus
);
505 status
= this->child_sa
->add(this->child_sa
, this->proposal
, prf_plus
);
507 prf_plus
->destroy(prf_plus
);
508 if (status
!= SUCCESS
)
514 status
= this->child_sa
->add_policies(this->child_sa
, this->tsi
, this->tsr
);
518 status
= this->child_sa
->add_policies(this->child_sa
, this->tsr
, this->tsi
);
520 if (status
!= SUCCESS
)
525 /* add to IKE_SA, and remove from transaction */
526 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLED
);
527 this->ike_sa
->add_child_sa(this->ike_sa
, this->child_sa
);
528 this->child_sa
= NULL
;
533 * Implementation of transaction_t.get_response.
535 static status_t
get_response(private_ike_auth_t
*this, message_t
*request
,
536 message_t
**result
, transaction_t
**next
)
539 identification_t
*my_id
, *other_id
;
542 iterator_t
*payloads
;
543 id_payload_t
*idi_request
= NULL
;
544 id_payload_t
*idr_request
= NULL
;
545 auth_payload_t
*auth_request
= NULL
;
546 cert_payload_t
*cert_request
= NULL
;
547 sa_payload_t
*sa_request
= NULL
;
548 ts_payload_t
*tsi_request
= NULL
;
549 ts_payload_t
*tsr_request
= NULL
;
550 id_payload_t
*idr_response
;
552 /* check if we already have built a response (retransmission) */
555 *result
= this->message
;
559 me
= this->ike_sa
->get_my_host(this->ike_sa
);
560 other
= this->ike_sa
->get_other_host(this->ike_sa
);
561 this->message_id
= request
->get_message_id(request
);
563 /* set up response */
564 response
= message_create();
565 response
->set_source(response
, me
->clone(me
));
566 response
->set_destination(response
, other
->clone(other
));
567 response
->set_exchange_type(response
, IKE_AUTH
);
568 response
->set_request(response
, FALSE
);
569 response
->set_message_id(response
, this->message_id
);
570 response
->set_ike_sa_id(response
, this->ike_sa
->get_id(this->ike_sa
));
571 this->message
= response
;
574 /* check message type */
575 if (request
->get_exchange_type(request
) != IKE_AUTH
)
577 this->logger
->log(this->logger
, ERROR
,
578 "IKE_AUTH response of invalid type, deleting IKE_SA");
582 /* Iterate over all payloads. */
583 payloads
= request
->get_payload_iterator(request
);
584 while (payloads
->has_next(payloads
))
587 payloads
->current(payloads
, (void**)&payload
);
588 switch (payload
->get_type(payload
))
591 idi_request
= (id_payload_t
*)payload
;
594 idr_request
= (id_payload_t
*)payload
;
597 auth_request
= (auth_payload_t
*)payload
;
600 cert_request
= (cert_payload_t
*)payload
;
602 case SECURITY_ASSOCIATION
:
603 sa_request
= (sa_payload_t
*)payload
;
605 case TRAFFIC_SELECTOR_INITIATOR
:
606 tsi_request
= (ts_payload_t
*)payload
;
608 case TRAFFIC_SELECTOR_RESPONDER
:
609 tsr_request
= (ts_payload_t
*)payload
;
613 status
= process_notifies(this, (notify_payload_t
*)payload
);
614 if (status
== FAILED
)
616 payloads
->destroy(payloads
);
617 /* we return SUCCESS, returned FAILED means do next transaction */
620 if (status
== DESTROY_ME
)
622 payloads
->destroy(payloads
);
629 this->logger
->log(this->logger
, ERROR
, "ignoring %s payload (%d)",
630 mapping_find(payload_type_m
, payload
->get_type(payload
)),
631 payload
->get_type(payload
));
636 payloads
->destroy(payloads
);
638 /* check if we have all payloads */
639 if (!(idi_request
&& auth_request
&& sa_request
&& tsi_request
&& tsr_request
))
641 build_notify(INVALID_SYNTAX
, response
, TRUE
);
642 this->logger
->log(this->logger
, AUDIT
,
643 "request message incomplete, deleting IKE_SA");
647 { /* process ID payload */
648 other_id
= idi_request
->get_identification(idi_request
);
651 my_id
= idr_request
->get_identification(idr_request
);
655 my_id
= identification_create_from_encoding(ID_ANY
, CHUNK_INITIALIZER
);
659 { /* get a policy and process traffic selectors */
660 linked_list_t
*my_ts
, *other_ts
;
662 my_ts
= tsr_request
->get_traffic_selectors(tsr_request
);
663 other_ts
= tsi_request
->get_traffic_selectors(tsi_request
);
665 this->policy
= charon
->policies
->get_policy(charon
->policies
,
671 this->tsr
= this->policy
->select_my_traffic_selectors(this->policy
, my_ts
, me
);
672 this->tsi
= this->policy
->select_other_traffic_selectors(this->policy
, other_ts
, other
);
674 destroy_ts_list(my_ts
);
675 destroy_ts_list(other_ts
);
677 /* TODO: We should check somehow if we have a policy, but with other
678 * traffic selectors. Then we would create a IKE_SA without a CHILD_SA. */
679 if (this->policy
== NULL
)
681 this->logger
->log(this->logger
, AUDIT
,
682 "no acceptable policy for IDs %s - %s found, deleting IKE_SA",
683 my_id
->get_string(my_id
), other_id
->get_string(other_id
));
684 my_id
->destroy(my_id
);
685 other_id
->destroy(other_id
);
686 build_notify(AUTHENTICATION_FAILED
, response
, TRUE
);
689 my_id
->destroy(my_id
);
691 /* get my id from policy, which must contain a fully qualified valid id */
692 my_id
= this->policy
->get_my_id(this->policy
);
693 this->ike_sa
->set_my_id(this->ike_sa
, my_id
->clone(my_id
));
694 this->ike_sa
->set_other_id(this->ike_sa
, other_id
);
696 idr_response
= id_payload_create_from_identification(FALSE
, my_id
);
697 response
->add_payload(response
, (payload_t
*)idr_response
);
700 if (this->connection
->get_cert_policy(this->connection
) != CERT_NEVER_SEND
)
701 { /* build certificate payload */
703 cert_payload_t
*cert_payload
;
705 cert
= charon
->credentials
->get_certificate(charon
->credentials
, my_id
);
708 this->logger
->log(this->logger
, ERROR
,
709 "could not find my certificate, cert payload omitted");
711 cert_payload
= cert_payload_create_from_x509(cert
);
712 response
->add_payload(response
, (payload_t
*)cert_payload
);
716 { /* process certificate payload */
717 import_certificate(this, cert_request
);
720 { /* process auth payload */
721 authenticator_t
*authenticator
;
722 auth_payload_t
*auth_response
;
723 auth_method_t auth_method
;
726 auth_method
= this->connection
->get_auth_method(this->connection
);
727 authenticator
= authenticator_create(this->ike_sa
, auth_method
);
728 status
= authenticator
->verify_auth_data(authenticator
, auth_request
,
730 this->nonce_r
, idi_request
,
732 if (status
!= SUCCESS
)
734 this->logger
->log(this->logger
, AUDIT
,
735 "authentication failed, deleting IKE_SA");
736 build_notify(AUTHENTICATION_FAILED
, response
, TRUE
);
737 authenticator
->destroy(authenticator
);
740 status
= authenticator
->compute_auth_data(authenticator
, &auth_response
,
742 this->nonce_i
, idr_response
,
744 authenticator
->destroy(authenticator
);
745 if (status
!= SUCCESS
)
747 this->logger
->log(this->logger
, AUDIT
,
748 "authentication data generation failed, deleting IKE_SA");
749 build_notify(AUTHENTICATION_FAILED
, response
, TRUE
);
752 response
->add_payload(response
, (payload_t
*)auth_response
);
755 { /* process SA payload */
756 linked_list_t
*proposal_list
;
757 sa_payload_t
*sa_response
;
758 ts_payload_t
*ts_response
;
760 u_int32_t soft_lifetime
, hard_lifetime
;
763 sa_response
= sa_payload_create();
765 /* get proposals from request, and select one with ours */
766 proposal_list
= sa_request
->get_proposals(sa_request
);
767 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "selecting proposals:");
768 this->proposal
= this->policy
->select_proposal(this->policy
, proposal_list
);
769 destroy_proposal_list(proposal_list
);
771 /* do we have a proposal? */
772 if (this->proposal
== NULL
)
774 this->logger
->log(this->logger
, AUDIT
,
775 "CHILD_SA proposals unacceptable, adding NO_PROPOSAL_CHOSEN notify");
776 build_notify(NO_PROPOSAL_CHOSEN
, response
, FALSE
);
778 /* do we have traffic selectors? */
779 else if (this->tsi
->get_count(this->tsi
) == 0 || this->tsr
->get_count(this->tsr
) == 0)
781 this->logger
->log(this->logger
, AUDIT
,
782 "CHILD_SA traffic selectors unacceptable, adding TS_UNACCEPTABLE notify");
783 build_notify(TS_UNACCEPTABLE
, response
, FALSE
);
787 /* create child sa */
788 soft_lifetime
= this->policy
->get_soft_lifetime(this->policy
);
789 hard_lifetime
= this->policy
->get_hard_lifetime(this->policy
);
790 use_natt
= this->ike_sa
->is_natt_enabled(this->ike_sa
);
791 this->child_sa
= child_sa_create(this->reqid
, me
, other
, my_id
, other_id
,
792 soft_lifetime
, hard_lifetime
,
793 this->policy
->get_updown(this->policy
),
795 this->child_sa
->set_name(this->child_sa
, this->policy
->get_name(this->policy
));
796 if (install_child_sa(this, FALSE
) != SUCCESS
)
798 this->logger
->log(this->logger
, ERROR
,
799 "installing CHILD_SA failed, adding NO_PROPOSAL_CHOSEN notify");
800 build_notify(NO_PROPOSAL_CHOSEN
, response
, FALSE
);
802 /* add proposal to sa payload */
803 sa_response
->add_proposal(sa_response
, this->proposal
);
805 response
->add_payload(response
, (payload_t
*)sa_response
);
807 /* add ts payload after sa payload */
808 ts_response
= ts_payload_create_from_traffic_selectors(TRUE
, this->tsi
);
809 response
->add_payload(response
, (payload_t
*)ts_response
);
810 ts_response
= ts_payload_create_from_traffic_selectors(FALSE
, this->tsr
);
811 response
->add_payload(response
, (payload_t
*)ts_response
);
813 /* set established state */
814 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
820 * Implementation of transaction_t.conclude
822 static status_t
conclude(private_ike_auth_t
*this, message_t
*response
,
823 transaction_t
**transaction
)
825 iterator_t
*payloads
;
827 identification_t
*other_id
;
828 ts_payload_t
*tsi_payload
= NULL
;
829 ts_payload_t
*tsr_payload
= NULL
;
830 id_payload_t
*idr_payload
= NULL
;
831 cert_payload_t
*cert_payload
= NULL
;
832 auth_payload_t
*auth_payload
= NULL
;
833 sa_payload_t
*sa_payload
= NULL
;
836 /* check message type */
837 if (response
->get_exchange_type(response
) != IKE_AUTH
)
839 this->logger
->log(this->logger
, ERROR
,
840 "IKE_AUTH response of invalid type, deleting IKE_SA");
844 me
= this->ike_sa
->get_my_host(this->ike_sa
);
845 other
= this->ike_sa
->get_other_host(this->ike_sa
);
847 /* Iterate over all payloads to collect them */
848 payloads
= response
->get_payload_iterator(response
);
849 while (payloads
->has_next(payloads
))
852 payloads
->current(payloads
, (void**)&payload
);
854 switch (payload
->get_type(payload
))
857 idr_payload
= (id_payload_t
*)payload
;
860 auth_payload
= (auth_payload_t
*)payload
;
863 cert_payload
= (cert_payload_t
*)payload
;
865 case SECURITY_ASSOCIATION
:
866 sa_payload
= (sa_payload_t
*)payload
;
868 case TRAFFIC_SELECTOR_INITIATOR
:
869 tsi_payload
= (ts_payload_t
*)payload
;
871 case TRAFFIC_SELECTOR_RESPONDER
:
872 tsr_payload
= (ts_payload_t
*)payload
;
876 status
= process_notifies(this, (notify_payload_t
*)payload
);
877 if (status
== FAILED
)
879 payloads
->destroy(payloads
);
880 /* we return SUCCESS, returned FAILED means do next transaction */
883 if (status
== DESTROY_ME
)
885 payloads
->destroy(payloads
);
892 this->logger
->log(this->logger
, CONTROL
, "ignoring payload %s (%d)",
893 mapping_find(payload_type_m
, payload
->get_type(payload
)),
894 payload
->get_type(payload
));
899 payloads
->destroy(payloads
);
901 if (!(idr_payload
&& auth_payload
&& sa_payload
&& tsi_payload
&& tsr_payload
))
903 this->logger
->log(this->logger
, AUDIT
, "response message incomplete, deleting IKE_SA");
907 { /* process idr payload */
908 identification_t
*configured_other_id
;
911 other_id
= idr_payload
->get_identification(idr_payload
);
912 configured_other_id
= this->policy
->get_other_id(this->policy
);
914 if (!other_id
->matches(other_id
, configured_other_id
, &wildcards
))
916 other_id
->destroy(other_id
);
917 this->logger
->log(this->logger
, AUDIT
,
918 "other peer uses unacceptable ID (%s, excepted %s), deleting IKE_SA",
919 other_id
->get_string(other_id
),
920 configured_other_id
->get_string(configured_other_id
));
923 /* update other ID. It was already set, but may contain wildcards */
924 this->ike_sa
->set_other_id(this->ike_sa
, other_id
);
928 { /* process cert payload */
929 import_certificate(this, cert_payload
);
932 { /* authenticate peer */
933 authenticator_t
*authenticator
;
934 auth_method_t auth_method
;
937 auth_method
= this->connection
->get_auth_method(this->connection
);
938 authenticator
= authenticator_create(this->ike_sa
, auth_method
);
939 status
= authenticator
->verify_auth_data(authenticator
, auth_payload
,
941 this->nonce_i
, idr_payload
,
943 authenticator
->destroy(authenticator
);
944 if (status
!= SUCCESS
)
946 this->logger
->log(this->logger
, AUDIT
, "authentication failed, deleting IKE_SA");
951 { /* process traffic selectors for us */
952 linked_list_t
*ts_received
= tsi_payload
->get_traffic_selectors(tsi_payload
);
953 this->tsi
= this->policy
->select_my_traffic_selectors(this->policy
, ts_received
, me
);
954 destroy_ts_list(ts_received
);
957 { /* process traffic selectors for other */
958 linked_list_t
*ts_received
= tsr_payload
->get_traffic_selectors(tsr_payload
);
959 this->tsr
= this->policy
->select_other_traffic_selectors(this->policy
, ts_received
, other
);
960 destroy_ts_list(ts_received
);
963 { /* process sa payload */
964 linked_list_t
*proposal_list
;
966 proposal_list
= sa_payload
->get_proposals(sa_payload
);
967 /* we have to re-check here if other's selection is valid */
968 this->proposal
= this->policy
->select_proposal(this->policy
, proposal_list
);
969 destroy_proposal_list(proposal_list
);
971 /* everything fine to create CHILD? */
972 if (this->proposal
== NULL
||
973 this->tsi
->get_count(this->tsi
) == 0 ||
974 this->tsr
->get_count(this->tsr
) == 0 ||
977 this->logger
->log(this->logger
, AUDIT
,
978 "CHILD_SA creation failed");
982 if (install_child_sa(this, TRUE
) != SUCCESS
)
984 this->logger
->log(this->logger
, ERROR
,
985 "installing CHILD_SA failed, no CHILD_SA built");
990 this->ike_sa
->set_state(this->ike_sa
, IKE_ESTABLISHED
);
995 * implements transaction_t.destroy
997 static void destroy(private_ike_auth_t
*this)
999 DESTROY_IF(this->message
);
1000 DESTROY_IF(this->proposal
);
1001 DESTROY_IF(this->child_sa
);
1002 DESTROY_IF(this->policy
);
1003 DESTROY_IF(this->connection
);
1004 destroy_ts_list(this->tsi
);
1005 destroy_ts_list(this->tsr
);
1006 chunk_free(&this->nonce_i
);
1007 chunk_free(&this->nonce_r
);
1008 chunk_free(&this->init_request
);
1009 chunk_free(&this->init_response
);
1014 * Described in header.
1016 ike_auth_t
*ike_auth_create(ike_sa_t
*ike_sa
)
1018 private_ike_auth_t
*this = malloc_thing(private_ike_auth_t
);
1020 /* transaction interface functions */
1021 this->public.transaction
.get_request
= (status_t(*)(transaction_t
*,message_t
**))get_request
;
1022 this->public.transaction
.get_response
= (status_t(*)(transaction_t
*,message_t
*,message_t
**,transaction_t
**))get_response
;
1023 this->public.transaction
.conclude
= (status_t(*)(transaction_t
*,message_t
*,transaction_t
**))conclude
;
1024 this->public.transaction
.get_message_id
= (u_int32_t(*)(transaction_t
*))get_message_id
;
1025 this->public.transaction
.requested
= (u_int32_t(*)(transaction_t
*))requested
;
1026 this->public.transaction
.destroy
= (void(*)(transaction_t
*))destroy
;
1028 /* public functions */
1029 this->public.set_config
= (void(*)(ike_auth_t
*,connection_t
*,policy_t
*))set_config
;
1030 this->public.set_reqid
= (void(*)(ike_auth_t
*,u_int32_t
))set_reqid
;
1031 this->public.set_nonces
= (void(*)(ike_auth_t
*,chunk_t
,chunk_t
))set_nonces
;
1032 this->public.set_init_messages
= (void(*)(ike_auth_t
*,chunk_t
,chunk_t
))set_init_messages
;
1035 this->ike_sa
= ike_sa
;
1036 this->message_id
= 0;
1037 this->message
= NULL
;
1038 this->requested
= 0;
1039 this->nonce_i
= CHUNK_INITIALIZER
;
1040 this->nonce_r
= CHUNK_INITIALIZER
;
1041 this->init_request
= CHUNK_INITIALIZER
;
1042 this->init_response
= CHUNK_INITIALIZER
;
1043 this->child_sa
= NULL
;
1044 this->proposal
= NULL
;
1047 this->build_child
= TRUE
;
1049 this->logger
= logger_manager
->get_logger(logger_manager
, IKE_SA
);
1051 return &this->public;