From: Tobias Brunner Date: Wed, 21 Jun 2023 13:57:38 +0000 (+0200) Subject: child-rekey: Correctly encode protocol/SPI in CHILD_SA_NOT_FOUND notify X-Git-Tag: android-2.4.2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=849c2c9707e00fc5210bd389631a2fc1a97089e6;p=thirdparty%2Fstrongswan.git child-rekey: Correctly encode protocol/SPI in CHILD_SA_NOT_FOUND notify As specified in RFC 7296, section 2.25: The SA that the initiator attempted to rekey is indicated by the SPI field in the Notify payload, which is copied from the SPI field in the REKEY_SA notification. So we copy that and the protocol verbatim. --- diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c index 9281c6339d..124f9b3372 100644 --- a/src/libcharon/sa/ikev2/tasks/child_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c @@ -58,6 +58,11 @@ struct private_child_rekey_t { */ uint32_t spi; + /** + * Encoded SPI in REKEY_SA notify if no CHILD_SA is found + */ + chunk_t spi_data; + /** * the CHILD_CREATE task which is reused to simplify rekeying */ @@ -145,12 +150,17 @@ static void find_child(private_child_rekey_t *this, message_t *message) { child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, FALSE); + /* ignore rekeyed/deleted CHILD_SAs we keep around */ if (child_sa && - child_sa->get_state(child_sa) == CHILD_DELETED) - { /* ignore rekeyed CHILD_SAs we keep around */ - return; + child_sa->get_state(child_sa) != CHILD_DELETED) + { + this->child_sa = child_sa; } - this->child_sa = child_sa; + } + if (!this->child_sa) + { + this->protocol = protocol; + this->spi_data = chunk_clone(notify->get_spi_data(notify)); } } } @@ -248,6 +258,7 @@ METHOD(task_t, process_r, status_t, METHOD(task_t, build_r, status_t, private_child_rekey_t *this, message_t *message) { + notify_payload_t *notify; child_cfg_t *config; uint32_t reqid; child_sa_state_t state; @@ -255,8 +266,12 @@ METHOD(task_t, build_r, status_t, if (!this->child_sa) { - DBG1(DBG_IKE, "unable to rekey, CHILD_SA not found"); - message->add_notify(message, TRUE, CHILD_SA_NOT_FOUND, chunk_empty); + DBG1(DBG_IKE, "unable to rekey, %N CHILD_SA with SPI %+B not found", + protocol_id_names, this->protocol, &this->spi_data); + notify = notify_payload_create_from_protocol_and_type(PLV2_NOTIFY, + this->protocol, CHILD_SA_NOT_FOUND); + notify->set_spi_data(notify, this->spi_data); + message->add_payload(message, (payload_t*)notify); return SUCCESS; } if (this->child_sa->get_state(this->child_sa) == CHILD_DELETING) @@ -606,6 +621,7 @@ METHOD(task_t, destroy, void, this->child_delete->task.destroy(&this->child_delete->task); } DESTROY_IF(this->collision); + chunk_free(&this->spi_data); free(this); }