From: Tobias Brunner Date: Tue, 5 Nov 2019 15:42:58 +0000 (+0100) Subject: ike-init: Indicate support for IKE_INTERMEDIATE X-Git-Tag: 6.0.0rc1~56^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7ad610a140d20bca67b427e61b69d1661a0b6403;p=thirdparty%2Fstrongswan.git ike-init: Indicate support for IKE_INTERMEDIATE --- diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 1c5333db87..ea81de2103 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -161,7 +161,7 @@ enum ike_extension_t { EXT_IKE_MESSAGE_ID_SYNC = (1<<14), /** - * Postquantum Preshared Keys, draft-ietf-ipsecme-qr-ikev2 + * Postquantum Preshared Keys, RFC 8784 */ EXT_PPK = (1<<15), @@ -169,6 +169,11 @@ enum ike_extension_t { * Responder accepts childless IKE_SAs, RFC 6023 */ EXT_IKE_CHILDLESS = (1<<16), + + /** + * IKEv2 Intermediate Exchange, RFC 9242 + */ + EXT_IKE_INTERMEDIATE = (1<<17), }; /** diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index 4eda3a0620..44a89f9eb2 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -348,6 +348,7 @@ static bool build_payloads(private_ike_init_t *this, message_t *message) proposal_t *proposal; enumerator_t *enumerator; ike_cfg_t *ike_cfg; + bool additional_ke = FALSE; id = this->ike_sa->get_id(this->ike_sa); @@ -372,6 +373,8 @@ static bool build_payloads(private_ike_init_t *this, message_t *message) proposal_list->remove_at(proposal_list, enumerator); other_ke_methods->insert_last(other_ke_methods, proposal); } + additional_ke = additional_ke || + proposal_has_additional_ke(proposal); } enumerator->destroy(enumerator); /* add proposals that don't contain the selected group */ @@ -394,6 +397,7 @@ static bool build_payloads(private_ike_init_t *this, message_t *message) this->proposal->set_spi(this->proposal, id->get_responder_spi(id)); } sa_payload = sa_payload_create_from_proposal_v2(this->proposal); + additional_ke = proposal_has_additional_ke(this->proposal); } message->add_payload(message, (payload_t*)sa_payload); @@ -467,6 +471,16 @@ static bool build_payloads(private_ike_init_t *this, message_t *message) message->add_notify(message, FALSE, CHILDLESS_IKEV2_SUPPORTED, chunk_empty); } + if (!this->old_sa && additional_ke) + { + if (this->initiator || + this->ike_sa->supports_extension(this->ike_sa, + EXT_IKE_INTERMEDIATE)) + { + message->add_notify(message, FALSE, INTERMEDIATE_EXCHANGE_SUPPORTED, + chunk_empty); + } + } return TRUE; } @@ -726,6 +740,13 @@ static void process_payloads(private_ike_init_t *this, message_t *message) EXT_IKE_CHILDLESS); } break; + case INTERMEDIATE_EXCHANGE_SUPPORTED: + if (!this->old_sa) + { + this->ike_sa->enable_extension(this->ike_sa, + EXT_IKE_INTERMEDIATE); + } + break; default: /* other notifies are handled elsewhere */ break; @@ -1163,6 +1184,14 @@ METHOD(task_t, build_r, status_t, if (key_exchange_done(this) == NEED_MORE) { + if (!this->old_sa && + !this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_INTERMEDIATE)) + { + DBG1(DBG_IKE, "peer didn't send %N while proposing multiple key " + "exchanges", notify_type_names, INTERMEDIATE_EXCHANGE_SUPPORTED); + message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); + return FAILED; + } /* use other exchange type for additional key exchanges */ this->public.task.build = _build_r_multi_ke; this->public.task.process = _process_r_multi_ke; @@ -1412,6 +1441,13 @@ METHOD(task_t, process_i, status_t, if (key_exchange_done(this) == NEED_MORE) { + if (!this->old_sa && + !this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_INTERMEDIATE)) + { + DBG1(DBG_IKE, "peer didn't send %N while accepting multiple key " + "exchanges", notify_type_names, INTERMEDIATE_EXCHANGE_SUPPORTED); + return FAILED; + } /* use other exchange type for additional key exchanges */ this->public.task.build = _build_i_multi_ke; this->public.task.process = _process_i_multi_ke;