From: Tobias Brunner Date: Fri, 5 Jul 2019 09:01:42 +0000 (+0200) Subject: message: Fix payload type in last unprotected payload of a fragmented message X-Git-Tag: 5.9.7dr2~1^2~19 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=c1987aefbe6393eb3d37d8362acc0b73af0bc350;p=thirdparty%2Fstrongswan.git message: Fix payload type in last unprotected payload of a fragmented message --- diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index db51aa714f..5156436f85 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -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);