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 */
+ this->payloads->get_first(this->payloads, (void**)&payload);
+ 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);
+
+ /* FIXME: copy flags */
+ 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
*/
.get_fragments = _get_fragments,
.get_metadata = _get_metadata,
.set_metadata = _set_metadata,
+ .get_plain = _get_plain,
.destroy = _destroy,
},
.exchange_type = EXCHANGE_TYPE_UNDEFINED,
*/
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().
*