]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
message: Fix payload type in last unprotected payload of a fragmented message
authorTobias Brunner <tobias@strongswan.org>
Fri, 5 Jul 2019 09:01:42 +0000 (11:01 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 29 Jun 2022 08:28:50 +0000 (10:28 +0200)
src/libcharon/encoding/message.c

index db51aa714fec93f3938db34f1cdc0958f83f01c1..5156436f853dcae5981a8169e3b00e72576829a4 100644 (file)
@@ -1565,7 +1565,7 @@ static encrypted_payload_t* wrap_payloads(private_message_t *this)
                }
        }
        if (encrypted)
-       {       /* simply adopt all the unencrypted payloads */
+       {       /* simply adopt all the unprotected payloads */
                this->payloads->destroy(this->payloads);
                this->payloads = payloads;
                return encrypted;
@@ -1655,7 +1655,7 @@ static ike_header_t *create_header(private_message_t *this)
  *
  * The generator and the possible encrypted payload are returned.  The latter
  * is not yet encrypted (but the transform is set).  It is also not added to
- * the payload list (so unless there are unencrypted payloads that list will
+ * the payload list (so unless there are unprotected payloads that list will
  * be empty afterwards).
  */
 static status_t generate_message(private_message_t *this, keymat_t *keymat,
@@ -1943,7 +1943,7 @@ static message_t *create_fragment(private_message_t *this, payload_type_t next,
                        /* only in the first fragment is this set to the type of the first
                         * payload in the encrypted payload */
                        fragment->set_next_type(fragment, next);
-                       /* move unencrypted payloads to the first fragment */
+                       /* move unprotected payloads to the first fragment */
                        enumerator = this->payloads->create_enumerator(this->payloads);
                        while (enumerator->enumerate(enumerator, &payload))
                        {
@@ -2096,7 +2096,7 @@ METHOD(message_t, fragment, status_t,
                /* padding and padding length */
                frag_len = round_down(frag_len, aead->get_block_size(aead));
                REDUCE_FRAG_LEN(frag_len, 1);
-               /* TODO-FRAG: if there are unencrypted payloads, should we account for
+               /* TODO-FRAG: if there are unprotected payloads, should we account for
                 * their length in the first fragment? we still would have to add
                 * an encrypted fragment payload (albeit empty), even so we couldn't
                 * prevent IP fragmentation in every case */
@@ -2894,7 +2894,7 @@ METHOD(message_t, add_fragment_v2, status_t,
                /* the first fragment denotes the payload type of the first payload in
                 * the original encrypted payload, cache that */
                this->first_payload = payload->get_next_type(payload);
-               /* move all unencrypted payloads contained in the first fragment */
+               /* move all unprotected payloads contained in the first fragment */
                enumerator = message->create_payload_enumerator(message);
                while (enumerator->enumerate(enumerator, &payload))
                {
@@ -2920,10 +2920,18 @@ METHOD(message_t, add_fragment_v2, status_t,
 
        data = merge_fragments(this, message);
 
+       /* use the cached next payload type from the SKF of the first fragment */
        encrypted = encrypted_payload_create_from_plain(this->first_payload, data);
        encrypted->set_transform(encrypted, aead);
+
+       if (this->payloads->get_last(this->payloads, (void**)&payload) == SUCCESS)
+       {       /* if there are any unprotected payloads, update the last one's next
+                * payload type (it points to an SKF instead of an SK) */
+               payload->set_next_type(payload, encrypted->payload_interface.get_type(
+                                                                                               &encrypted->payload_interface));
+       }
        this->payloads->insert_last(this->payloads, encrypted);
-       /* update next payload type (could be an unencrypted payload) */
+       /* update payload type in the header (could be an unprotected payload) */
        this->payloads->get_first(this->payloads, (void**)&payload);
        this->first_payload = payload->get_type(payload);