mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
message: Add method to generate data to authenticate IKE_INTERMEDIATE exchanges
This commit is contained in:
parent
5c439bb8a3
commit
b9c69f9080
@ -1984,6 +1984,82 @@ METHOD(message_t, generate, status_t,
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(message_t, get_plain, bool,
|
||||||
|
private_message_t *this, chunk_t *plain)
|
||||||
|
{
|
||||||
|
generator_t *generator, *enc_generator;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
ike_header_t *ike_header;
|
||||||
|
payload_t *payload;
|
||||||
|
encrypted_payload_t *encrypted;
|
||||||
|
chunk_t int_auth_a, enc_header, int_auth_p;
|
||||||
|
struct {
|
||||||
|
uint8_t next_payload;
|
||||||
|
uint8_t flags;
|
||||||
|
uint16_t length;
|
||||||
|
} __attribute__((packed)) header = {};
|
||||||
|
uint32_t *lenpos;
|
||||||
|
|
||||||
|
if (this->major_version == IKEV1_MAJOR_VERSION ||
|
||||||
|
this->exchange_type != IKE_INTERMEDIATE)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we expect to be called after the message has either been parsed
|
||||||
|
* or already generated once, so we don't modify payload order */
|
||||||
|
generator = generator_create_no_dbg();
|
||||||
|
ike_header = create_header(this);
|
||||||
|
payload = (payload_t*)ike_header;
|
||||||
|
/* for parsed messages the payloads were already extracted from the
|
||||||
|
* encrypted payload, if there were any unprotected paylaods we wouldn't
|
||||||
|
* know. lets assume there aren't any (also for sent messages) */
|
||||||
|
payload->set_next_type(payload, PLV2_ENCRYPTED);
|
||||||
|
|
||||||
|
generator->generate_payload(generator, payload);
|
||||||
|
int_auth_a = generator->get_chunk(generator, &lenpos);
|
||||||
|
|
||||||
|
enc_generator = generator_create_no_dbg();
|
||||||
|
this->payloads->get_first(this->payloads, (void**)&payload);
|
||||||
|
if (payload && payload->get_type(payload) == PLV2_ENCRYPTED)
|
||||||
|
{
|
||||||
|
/* we have to generate only the contents of this payload,
|
||||||
|
* not the payload itself, the header is added manually */
|
||||||
|
encrypted = (encrypted_payload_t*)payload;
|
||||||
|
|
||||||
|
encrypted->generate_payloads(encrypted, enc_generator);
|
||||||
|
|
||||||
|
header.next_payload = payload->get_next_type(payload);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* as mentioned above, assume all received payloads were contained in an
|
||||||
|
* encrypted payload */
|
||||||
|
enumerator = create_payload_enumerator(this);
|
||||||
|
while (enumerator->enumerate(enumerator, &payload))
|
||||||
|
{
|
||||||
|
enc_generator->generate_payload(enc_generator, payload);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
header.next_payload = this->first_payload;
|
||||||
|
}
|
||||||
|
int_auth_p = enc_generator->get_chunk(enc_generator, NULL);
|
||||||
|
|
||||||
|
/* flags are currently no copied, but the critical bit and the reserved
|
||||||
|
* bits MUST be zero for encrypted payloads, so that's what we assume */
|
||||||
|
enc_header = chunk_from_thing(header);
|
||||||
|
header.length = htons(enc_header.len + int_auth_p.len);
|
||||||
|
|
||||||
|
htoun32(lenpos, int_auth_a.len + enc_header.len + int_auth_p.len);
|
||||||
|
*plain = chunk_cat("ccc", int_auth_a, enc_header, int_auth_p);
|
||||||
|
|
||||||
|
enc_generator->destroy(enc_generator);
|
||||||
|
generator->destroy(generator);
|
||||||
|
ike_header->destroy(ike_header);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a (basic) clone of the given message
|
* Creates a (basic) clone of the given message
|
||||||
*/
|
*/
|
||||||
@ -3131,6 +3207,7 @@ message_t *message_create_from_packet(packet_t *packet)
|
|||||||
.get_fragments = _get_fragments,
|
.get_fragments = _get_fragments,
|
||||||
.get_metadata = _get_metadata,
|
.get_metadata = _get_metadata,
|
||||||
.set_metadata = _set_metadata,
|
.set_metadata = _set_metadata,
|
||||||
|
.get_plain = _get_plain,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.exchange_type = EXCHANGE_TYPE_UNDEFINED,
|
.exchange_type = EXCHANGE_TYPE_UNDEFINED,
|
||||||
|
@ -258,6 +258,21 @@ struct message_t {
|
|||||||
*/
|
*/
|
||||||
status_t (*generate) (message_t *this, keymat_t *keymat, packet_t **packet);
|
status_t (*generate) (message_t *this, keymat_t *keymat, packet_t **packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the plaintext encoding of this message as needed to authenticate
|
||||||
|
* IKE_INTERMEDIATE exchanges.
|
||||||
|
*
|
||||||
|
* The data returned is the concatenation of the IKE header and plaintext
|
||||||
|
* payloads (if any) up until the end of the header of the Encrypted
|
||||||
|
* Payload followed by the plaintext data of the Encrypted Payload (if any).
|
||||||
|
* Lenght fields are adjusted to only contain that of returned data (e.g.
|
||||||
|
* IV or padding is ignored).
|
||||||
|
*
|
||||||
|
* @param[out] plain plaintext encoding (allocated)
|
||||||
|
* @return TRUE if generated successfully
|
||||||
|
*/
|
||||||
|
bool (*get_plain)(message_t *this, chunk_t *plain);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the message has already been encoded using generate().
|
* Check if the message has already been encoded using generate().
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user