]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
ike-init: Indicate support for IKE_INTERMEDIATE
authorTobias Brunner <tobias@strongswan.org>
Tue, 5 Nov 2019 15:42:58 +0000 (16:42 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 7 Aug 2024 14:20:19 +0000 (16:20 +0200)
src/libcharon/sa/ike_sa.h
src/libcharon/sa/ikev2/tasks/ike_init.c

index 1c5333db87565dd99893e7168b3c558275a0787d..ea81de2103adfc8051905019e8fa4549cc9a4bf6 100644 (file)
@@ -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),
 };
 
 /**
index 4eda3a0620c76299fa0e663f22b4392aeaaf23c0..44a89f9eb288856cea0036f505e2c2d704f70d53 100644 (file)
@@ -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;