aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/encoding/payloads/encryption_payload.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/encoding/payloads/encryption_payload.c')
-rw-r--r--src/charon/encoding/payloads/encryption_payload.c367
1 files changed, 164 insertions, 203 deletions
diff --git a/src/charon/encoding/payloads/encryption_payload.c b/src/charon/encoding/payloads/encryption_payload.c
index caf34fbaa..d32e6c902 100644
--- a/src/charon/encoding/payloads/encryption_payload.c
+++ b/src/charon/encoding/payloads/encryption_payload.c
@@ -29,7 +29,6 @@
#include <daemon.h>
#include <encoding/payloads/encodings.h>
#include <utils/linked_list.h>
-#include <utils/logger.h>
#include <encoding/generator.h>
#include <encoding/parser.h>
#include <utils/iterator.h>
@@ -37,8 +36,6 @@
#include <crypto/signers/signer.h>
-
-
typedef struct private_encryption_payload_t private_encryption_payload_t;
/**
@@ -95,32 +92,6 @@ struct private_encryption_payload_t {
* Contained payloads of this encrpytion_payload.
*/
linked_list_t *payloads;
-
- /**
- * logger for this payload, uses MESSAGE context
- */
- logger_t *logger;
-
- /**
- * @brief Computes the length of this payload.
- *
- * @param this calling private_encryption_payload_t object
- */
- void (*compute_length) (private_encryption_payload_t *this);
-
- /**
- * @brief Generate payloads (unencrypted) in chunk decrypted.
- *
- * @param this calling private_encryption_payload_t object
- */
- void (*generate) (private_encryption_payload_t *this);
-
- /**
- * @brief Parse payloads from a (unencrypted) chunk.
- *
- * @param this calling private_encryption_payload_t object
- */
- status_t (*parse) (private_encryption_payload_t *this);
};
/**
@@ -212,11 +183,45 @@ static void set_next_type(private_encryption_payload_t *this, payload_type_t typ
}
/**
+ * (re-)compute the lenght of the whole payload
+ */
+static void compute_length(private_encryption_payload_t *this)
+{
+ iterator_t *iterator;
+ size_t block_size, length = 0;
+ iterator = this->payloads->create_iterator(this->payloads, TRUE);
+
+ /* count payload length */
+ while (iterator->has_next(iterator))
+ {
+ payload_t *current_payload;
+ iterator->current(iterator, (void **) &current_payload);
+ length += current_payload->get_length(current_payload);
+ }
+ iterator->destroy(iterator);
+
+ if (this->crypter && this->signer)
+ {
+ /* append one byte for padding length */
+ length++;
+ /* append padding */
+ block_size = this->crypter->get_block_size(this->crypter);
+ length += block_size - length % block_size;
+ /* add iv */
+ length += block_size;
+ /* add signature */
+ length += this->signer->get_block_size(this->signer);
+ }
+ length += ENCRYPTION_PAYLOAD_HEADER_LENGTH;
+ this->payload_length = length;
+}
+
+/**
* Implementation of payload_t.get_length.
*/
static size_t get_length(private_encryption_payload_t *this)
{
- this->compute_length(this);
+ compute_length(this);
return this->payload_length;
}
@@ -245,7 +250,7 @@ static void add_payload(private_encryption_payload_t *this, payload_t *payload)
}
payload->set_next_type(payload, NO_PAYLOAD);
this->payloads->insert_last(this->payloads, (void*)payload);
- this->compute_length(this);
+ compute_length(this);
}
/**
@@ -264,6 +269,60 @@ static size_t get_payload_count(private_encryption_payload_t *this)
return this->payloads->get_count(this->payloads);
}
+/**
+ * Generate payload before encryption.
+ */
+static void generate(private_encryption_payload_t *this)
+{
+ payload_t *current_payload, *next_payload;
+ generator_t *generator;
+ iterator_t *iterator;
+
+ /* recalculate length before generating */
+ compute_length(this);
+
+ /* create iterator */
+ iterator = this->payloads->create_iterator(this->payloads, TRUE);
+
+ /* get first payload */
+ if (iterator->has_next(iterator))
+ {
+ iterator->current(iterator, (void**)&current_payload);
+ this->next_payload = current_payload->get_type(current_payload);
+ }
+ else
+ {
+ /* no paylads? */
+ DBG2(SIG_DBG_ENC, "generating contained payloads, but none available");
+ free(this->decrypted.ptr);
+ this->decrypted = CHUNK_INITIALIZER;
+ iterator->destroy(iterator);
+ return;
+ }
+
+ generator = generator_create();
+
+ /* build all payload, except last */
+ while(iterator->has_next(iterator))
+ {
+ iterator->current(iterator, (void**)&next_payload);
+ current_payload->set_next_type(current_payload, next_payload->get_type(next_payload));
+ generator->generate_payload(generator, current_payload);
+ current_payload = next_payload;
+ }
+ iterator->destroy(iterator);
+
+ /* build last payload */
+ current_payload->set_next_type(current_payload, NO_PAYLOAD);
+ generator->generate_payload(generator, current_payload);
+
+ /* free already generated data */
+ free(this->decrypted.ptr);
+
+ generator->write_to_chunk(generator, &(this->decrypted));
+ generator->destroy(generator);
+ DBG2(SIG_DBG_ENC, "successfully generated content in encryption payload");
+}
/**
* Implementation of encryption_payload_t.encrypt.
@@ -277,19 +336,18 @@ static status_t encrypt(private_encryption_payload_t *this)
if (this->signer == NULL || this->crypter == NULL)
{
- this->logger->log(this->logger, ERROR, "could not encrypt, signer/crypter not set");
+ DBG1(SIG_DBG_ENC, "could not encrypt, signer/crypter not set");
return INVALID_STATE;
}
/* for random data in iv and padding */
randomizer = randomizer_create();
-
-
+
/* build payload chunk */
- this->generate(this);
+ generate(this);
- this->logger->log(this->logger, CONTROL|LEVEL2, "encrypting payloads");
- this->logger->log_chunk(this->logger, RAW|LEVEL2, "data to encrypt", this->decrypted);
+ DBG2(SIG_DBG_ENC, "encrypting payloads");
+ DBG3(SIG_DBG_ENC, "data to encrypt %B", &this->decrypted);
/* build padding */
block_size = this->crypter->get_block_size(this->crypter);
@@ -320,8 +378,8 @@ static status_t encrypt(private_encryption_payload_t *this)
return status;
}
- this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before encryption with padding", to_crypt);
-
+ DBG3(SIG_DBG_ENC, "data before encryption with padding %B", &to_crypt);
+
/* encrypt to_crypt chunk */
free(this->encrypted.ptr);
status = this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
@@ -329,12 +387,11 @@ static status_t encrypt(private_encryption_payload_t *this)
free(to_crypt.ptr);
if (status != SUCCESS)
{
- this->logger->log(this->logger, ERROR|LEVEL1, "encryption failed");
+ DBG2(SIG_DBG_ENC, "encryption failed");
free(iv.ptr);
return status;
}
- this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after encryption", result);
-
+ DBG3(SIG_DBG_ENC, "data after encryption %B", &result);
/* build encrypted result with iv and signature */
this->encrypted.len = iv.len + result.len + this->signer->get_block_size(this->signer);
@@ -347,12 +404,58 @@ static status_t encrypt(private_encryption_payload_t *this)
free(result.ptr);
free(iv.ptr);
- this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after encryption with IV and (invalid) signature", this->encrypted);
+ DBG3(SIG_DBG_ENC, "data after encryption with IV and (invalid) signature %B",
+ &this->encrypted);
return SUCCESS;
}
/**
+ * Parse the payloads after decryption.
+ */
+static status_t parse(private_encryption_payload_t *this)
+{
+ parser_t *parser;
+ status_t status;
+ payload_type_t current_payload_type;
+
+ /* build a parser on the decrypted data */
+ parser = parser_create(this->decrypted);
+
+ current_payload_type = this->next_payload;
+ /* parse all payloads */
+ while (current_payload_type != NO_PAYLOAD)
+ {
+ payload_t *current_payload;
+
+ status = parser->parse_payload(parser, current_payload_type, (payload_t**)&current_payload);
+ if (status != SUCCESS)
+ {
+ parser->destroy(parser);
+ return PARSE_ERROR;
+ }
+
+ status = current_payload->verify(current_payload);
+ if (status != SUCCESS)
+ {
+ DBG1(SIG_DBG_ENC, "%N verification failed",
+ payload_type_names, current_payload->get_type(current_payload));
+ current_payload->destroy(current_payload);
+ parser->destroy(parser);
+ return VERIFY_ERROR;
+ }
+
+ /* get next payload type */
+ current_payload_type = current_payload->get_next_type(current_payload);
+
+ this->payloads->insert_last(this->payloads,current_payload);
+ }
+ parser->destroy(parser);
+ DBG2(SIG_DBG_ENC, "succesfully parsed content of encryption payload");
+ return SUCCESS;
+}
+
+/**
* Implementation of encryption_payload_t.encrypt.
*/
static status_t decrypt(private_encryption_payload_t *this)
@@ -361,14 +464,13 @@ static status_t decrypt(private_encryption_payload_t *this)
u_int8_t padding_length;
status_t status;
-
- this->logger->log(this->logger, CONTROL|LEVEL2, "decrypting encryption payload");
- this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before decryption with IV and (invalid) signature", this->encrypted);
-
+ DBG2(SIG_DBG_ENC, "decrypting encryption payload");
+ DBG3(SIG_DBG_ENC, "data before decryption with IV and (invalid) signature %B",
+ &this->encrypted);
if (this->signer == NULL || this->crypter == NULL)
{
- this->logger->log(this->logger, ERROR, "could not decrypt, no crypter/signer set");
+ DBG1(SIG_DBG_ENC, "could not decrypt, no crypter/signer set");
return INVALID_STATE;
}
@@ -386,22 +488,22 @@ static status_t decrypt(private_encryption_payload_t *this)
*/
if (concatenated.len < iv.len)
{
- this->logger->log(this->logger, ERROR, "could not decrypt, invalid input");
+ DBG1(SIG_DBG_ENC, "could not decrypt, invalid input");
return FAILED;
}
/* free previus data, if any */
free(this->decrypted.ptr);
- this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before decryption", concatenated);
+ DBG3(SIG_DBG_ENC, "data before decryption %B", &concatenated);
status = this->crypter->decrypt(this->crypter, concatenated, iv, &(this->decrypted));
if (status != SUCCESS)
{
- this->logger->log(this->logger, ERROR, "could not decrypt, decryption failed");
+ DBG1(SIG_DBG_ENC, "could not decrypt, decryption failed");
return FAILED;
}
- this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after decryption with padding", this->decrypted);
+ DBG3(SIG_DBG_ENC, "data after decryption with padding %B", &this->decrypted);
/* get padding length, sits just bevore signature */
@@ -413,16 +515,16 @@ static status_t decrypt(private_encryption_payload_t *this)
/* check size again */
if (padding_length > concatenated.len || this->decrypted.len < 0)
{
- this->logger->log(this->logger, ERROR, "decryption failed, invalid padding length found. Invalid key?");
+ DBG1(SIG_DBG_ENC, "decryption failed, invalid padding length found. Invalid key?");
/* decryption failed :-/ */
return FAILED;
}
/* free padding */
this->decrypted.ptr = realloc(this->decrypted.ptr, this->decrypted.len);
- this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after decryption without padding", this->decrypted);
- this->logger->log(this->logger, CONTROL|LEVEL2, "decryption successful, trying to parse content");
- return (this->parse(this));
+ DBG3(SIG_DBG_ENC, "data after decryption without padding %B", &this->decrypted);
+ DBG2(SIG_DBG_ENC, "decryption successful, trying to parse content");
+ return parse(this);
}
/**
@@ -444,14 +546,14 @@ static status_t build_signature(private_encryption_payload_t *this, chunk_t data
if (this->signer == NULL)
{
- this->logger->log(this->logger, ERROR, "unable to build signature, no signer set");
+ DBG1(SIG_DBG_ENC, "unable to build signature, no signer set");
return INVALID_STATE;
}
sig.len = this->signer->get_block_size(this->signer);
data_without_sig.len -= sig.len;
sig.ptr = data.ptr + data_without_sig.len;
- this->logger->log(this->logger, CONTROL|LEVEL2, "building signature");
+ DBG2(SIG_DBG_ENC, "building signature");
this->signer->get_signature(this->signer, data_without_sig, sig.ptr);
return SUCCESS;
}
@@ -466,14 +568,14 @@ static status_t verify_signature(private_encryption_payload_t *this, chunk_t dat
if (this->signer == NULL)
{
- this->logger->log(this->logger, ERROR, "unable to verify signature, no signer set");
+ DBG1(SIG_DBG_ENC, "unable to verify signature, no signer set");
return INVALID_STATE;
}
/* find signature in data chunk */
sig.len = this->signer->get_block_size(this->signer);
if (data.len <= sig.len)
{
- this->logger->log(this->logger, ERROR|LEVEL1, "unable to verify signature, invalid input");
+ DBG1(SIG_DBG_ENC, "unable to verify signature, invalid input");
return FAILED;
}
sig.ptr = data.ptr + data.len - sig.len;
@@ -485,150 +587,15 @@ static status_t verify_signature(private_encryption_payload_t *this, chunk_t dat
if (!valid)
{
- this->logger->log(this->logger, ERROR|LEVEL1, "signature verification failed");
+ DBG1(SIG_DBG_ENC, "signature verification failed");
return FAILED;
}
- this->logger->log(this->logger, CONTROL|LEVEL2, "signature verification successful");
- return SUCCESS;
-}
-
-/**
- * Implementation of private_encryption_payload_t.generate.
- */
-static void generate(private_encryption_payload_t *this)
-{
- payload_t *current_payload, *next_payload;
- generator_t *generator;
- iterator_t *iterator;
-
- /* recalculate length before generating */
- this->compute_length(this);
-
- /* create iterator */
- iterator = this->payloads->create_iterator(this->payloads, TRUE);
-
- /* get first payload */
- if (iterator->has_next(iterator))
- {
- iterator->current(iterator, (void**)&current_payload);
- this->next_payload = current_payload->get_type(current_payload);
- }
- else
- {
- /* no paylads? */
- this->logger->log(this->logger, CONTROL|LEVEL1, "generating contained payloads, but no available");
- free(this->decrypted.ptr);
- this->decrypted = CHUNK_INITIALIZER;
- iterator->destroy(iterator);
- return;
- }
-
- generator = generator_create();
-
- /* build all payload, except last */
- while(iterator->has_next(iterator))
- {
- iterator->current(iterator, (void**)&next_payload);
- current_payload->set_next_type(current_payload, next_payload->get_type(next_payload));
- generator->generate_payload(generator, current_payload);
- current_payload = next_payload;
- }
- iterator->destroy(iterator);
-
- /* build last payload */
- current_payload->set_next_type(current_payload, NO_PAYLOAD);
- generator->generate_payload(generator, current_payload);
-
- /* free already generated data */
- free(this->decrypted.ptr);
-
- generator->write_to_chunk(generator, &(this->decrypted));
- generator->destroy(generator);
- this->logger->log(this->logger, CONTROL|LEVEL1, "successfully generated content in encrpytion payload");
-}
-
-/**
- * Implementation of private_encryption_payload_t.parse.
- */
-static status_t parse(private_encryption_payload_t *this)
-{
- parser_t *parser;
- status_t status;
- payload_type_t current_payload_type;
-
- /* build a parser on the decrypted data */
- parser = parser_create(this->decrypted);
-
- current_payload_type = this->next_payload;
- /* parse all payloads */
- while (current_payload_type != NO_PAYLOAD)
- {
- payload_t *current_payload;
-
- status = parser->parse_payload(parser, current_payload_type, (payload_t**)&current_payload);
- if (status != SUCCESS)
- {
- parser->destroy(parser);
- return PARSE_ERROR;
- }
-
- status = current_payload->verify(current_payload);
- if (status != SUCCESS)
- {
- this->logger->log(this->logger, ERROR, "%s verification failed",
- mapping_find(payload_type_m,current_payload->get_type(current_payload)));
- current_payload->destroy(current_payload);
- parser->destroy(parser);
- return VERIFY_ERROR;
- }
-
- /* get next payload type */
- current_payload_type = current_payload->get_next_type(current_payload);
-
- this->payloads->insert_last(this->payloads,current_payload);
- }
- parser->destroy(parser);
- this->logger->log(this->logger, CONTROL|LEVEL1, "succesfully parsed content of encryption payload");
+ DBG2(SIG_DBG_ENC, "signature verification successful");
return SUCCESS;
}
/**
- * Implementation of private_encryption_payload_t.compute_length.
- */
-static void compute_length(private_encryption_payload_t *this)
-{
- iterator_t *iterator;
- size_t block_size, length = 0;
- iterator = this->payloads->create_iterator(this->payloads, TRUE);
-
- /* count payload length */
- while (iterator->has_next(iterator))
- {
- payload_t *current_payload;
- iterator->current(iterator, (void **) &current_payload);
- length += current_payload->get_length(current_payload);
- }
- iterator->destroy(iterator);
-
- if (this->crypter && this->signer)
- {
- /* append one byte for padding length */
- length++;
- /* append padding */
- block_size = this->crypter->get_block_size(this->crypter);
- length += block_size - length % block_size;
- /* add iv */
- length += block_size;
- /* add signature */
- length += this->signer->get_block_size(this->signer);
- }
- length += ENCRYPTION_PAYLOAD_HEADER_LENGTH;
- this->payload_length = length;
-}
-
-
-/**
* Implementation of payload_t.destroy.
*/
static void destroy(private_encryption_payload_t *this)
@@ -675,12 +642,6 @@ encryption_payload_t *encryption_payload_create()
this->public.verify_signature = (status_t (*) (encryption_payload_t*, chunk_t)) verify_signature;
this->public.destroy = (void (*) (encryption_payload_t *)) destroy;
- /* private functions */
- this->compute_length = compute_length;
- this->generate = generate;
- this->parse = parse;
- this->logger = logger_manager->get_logger(logger_manager, ENCRYPTION_PAYLOAD);
-
/* set default values of the fields */
this->critical = FALSE;
this->next_payload = NO_PAYLOAD;