From e23b3bae41ea47b69a145892909492a59acae30c Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Tue, 15 Nov 2005 15:26:27 +0000 Subject: [PATCH] - nonce payload added - tested --- Source/charon/parser.c | 18 +++-- Source/charon/payloads/encodings.c | 1 + Source/charon/payloads/encodings.h | 12 ++- Source/charon/payloads/nonce_payload.c | 2 +- Source/charon/payloads/payload.c | 3 + Source/charon/testcases/parser_test.c | 104 ++++++++++++++++++++++++- Source/charon/testcases/parser_test.h | 2 +- 7 files changed, 130 insertions(+), 12 deletions(-) diff --git a/Source/charon/parser.c b/Source/charon/parser.c index bbb4bc689..e65f88ff6 100644 --- a/Source/charon/parser.c +++ b/Source/charon/parser.c @@ -304,7 +304,7 @@ static status_t parse_uint15(private_parser_t *this, int rule_number, u_int16_t /* caller interested in result ? */ if (output_pos != NULL) { - *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & 0xEFFF; + *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & ~0x8000; this->logger->log(this->logger, RAW, " => %d", *output_pos); } this->byte_pos += 2; @@ -507,8 +507,6 @@ static status_t parse_chunk(private_parser_t *this, int rule_number, chunk_t *ou return OUT_OF_RES; } memcpy(output_pos->ptr, this->byte_pos, length); - - this->logger->log_bytes(this->logger, RAW, " =>", output_pos->ptr, length); } this->byte_pos += length; @@ -712,16 +710,12 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case ATTRIBUTE_LENGTH_OR_VALUE: { - this->logger->log_bytes(this->logger, RAW, "ATTRIBUTE_LENGTH_OR_VALUE", this->byte_pos, 2); - if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS) { pld->destroy(pld); return PARSE_ERROR; } attribute_length = *(u_int16_t*)(output + rule->offset); - this->logger->log_bytes(this->logger, RAW, "ATTRIBUTE_LENGTH_OR_VALUE", output + rule->offset, 2); - break; } case ATTRIBUTE_VALUE: @@ -736,6 +730,16 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } break; } + case NONCE_DATA: + { + size_t nonce_length = payload_length - 4; + if (this->parse_chunk(this, rule_number, output + rule->offset, nonce_length) != SUCCESS) + { + pld->destroy(pld); + return PARSE_ERROR; + } + break; + } default: { this->logger->log(this->logger, ERROR, " no rule to parse rule %d %s (%d)", rule_number, mapping_find(encoding_type_t_mappings, rule->type), rule->type); diff --git a/Source/charon/payloads/encodings.c b/Source/charon/payloads/encodings.c index eb26819b1..327da633f 100644 --- a/Source/charon/payloads/encodings.c +++ b/Source/charon/payloads/encodings.c @@ -47,6 +47,7 @@ mapping_t encoding_type_t_mappings[] = { {ATTRIBUTE_TYPE, "ATTRIBUTE_TYPE"}, {ATTRIBUTE_LENGTH_OR_VALUE, "ATTRIBUTE_LENGTH_OR_VALUE"}, {ATTRIBUTE_VALUE, "ATTRIBUTE_VALUE"}, + {NONCE_DATA, "NONCE_DATA"}, {MAPPING_END, NULL} }; diff --git a/Source/charon/payloads/encodings.h b/Source/charon/payloads/encodings.h index 2c69d494c..f6315176f 100644 --- a/Source/charon/payloads/encodings.h +++ b/Source/charon/payloads/encodings.h @@ -296,7 +296,17 @@ enum encoding_type_e{ * * When parsing SPI_SIZE bytes are read and written into the chunk pointing to. */ - ATTRIBUTE_VALUE + ATTRIBUTE_VALUE, + + /** + * Representating a Nonce Data field + * + * When generating the content of the chunkt pointing to + * is written. + * + * When parsing (Payload Length - 4) bytes are read and written into the chunk pointing to. + */ + NONCE_DATA }; /** diff --git a/Source/charon/payloads/nonce_payload.c b/Source/charon/payloads/nonce_payload.c index 8126341a1..10070e3e9 100644 --- a/Source/charon/payloads/nonce_payload.c +++ b/Source/charon/payloads/nonce_payload.c @@ -97,7 +97,7 @@ encoding_rule_t nonce_payload_encodings[] = { /* Length of the whole nonce payload*/ { PAYLOAD_LENGTH, offsetof(private_nonce_payload_t, payload_length) }, /* some nonce bytes, lenth is defined in PAYLOAD_LENGTH */ - { NONCE, offsetof(private_nonce_payload_t, nonce) } + { NONCE_DATA, offsetof(private_nonce_payload_t, nonce) } }; /** diff --git a/Source/charon/payloads/payload.c b/Source/charon/payloads/payload.c index cf7a75b4f..22bb85bdc 100644 --- a/Source/charon/payloads/payload.c +++ b/Source/charon/payloads/payload.c @@ -26,6 +26,7 @@ #include "ike_header.h" #include "sa_payload.h" +#include "nonce_payload.h" @@ -76,6 +77,8 @@ payload_t *payload_create(payload_type_t type) return (payload_t*)transform_substructure_create(); case TRANSFORM_ATTRIBUTE: return (payload_t*)transform_attribute_create(); + case NONCE: + return (payload_t*)nonce_payload_create(); default: return NULL; } diff --git a/Source/charon/testcases/parser_test.c b/Source/charon/testcases/parser_test.c index 4d1b36546..354073912 100644 --- a/Source/charon/testcases/parser_test.c +++ b/Source/charon/testcases/parser_test.c @@ -30,6 +30,7 @@ #include "../payloads/encodings.h" #include "../payloads/ike_header.h" #include "../payloads/sa_payload.h" +#include "../payloads/nonce_payload.h" extern logger_manager_t *global_logger_manager; @@ -93,6 +94,7 @@ void test_parser_with_sa_payload(tester_t *tester) sa_payload_t *sa_payload; status_t status; chunk_t sa_chunk; + linked_list_iterator_t *proposals, *transforms, *attributes; u_int8_t sa_bytes[] = { 0x00,0x80,0x00,0x24, /* payload header*/ @@ -100,9 +102,9 @@ void test_parser_with_sa_payload(tester_t *tester) 0x01,0x02,0x04,0x05, 0x01,0x02,0x03,0x04, /* spi */ 0x00,0x00,0x00,0x14, /* transform */ - 0x02,0x00,0x00,0x03, + 0x07,0x00,0x00,0x03, 0x80,0x01,0x00,0x05, /* attribute without length */ - 0x00,0x01,0x00,0x04, /* attribute with lenngth */ + 0x00,0x03,0x00,0x04, /* attribute with lenngth */ 0x01,0x02,0x03,0x04 @@ -123,6 +125,104 @@ void test_parser_with_sa_payload(tester_t *tester) return; } + + sa_payload->create_proposal_substructure_iterator(sa_payload, &proposals, TRUE); + while (proposals->has_next(proposals)) + { + proposal_substructure_t *proposal; + proposals->current(proposals, (void**)&proposal); + chunk_t spi; + u_int8_t spi_should[] = {0x01, 0x02, 0x03, 0x04}; + + tester->assert_true(tester,(proposal->get_proposal_number(proposal) == 1),"proposal number"); + tester->assert_true(tester,(proposal->get_protocol_id(proposal) == 2),"proposal id"); + spi = proposal->get_spi(proposal); + tester->assert_false(tester,(memcmp(&spi_should, spi.ptr, spi.len)),"proposal spi"); + + proposal->create_transform_substructure_iterator(proposal, &transforms, TRUE); + while(transforms->has_next(transforms)) + { + transform_substructure_t *transform; + int loopi; + transforms->current(transforms, (void**)&transform); + tester->assert_true(tester,(transform->get_transform_type(transform) == 7),"transform type"); + tester->assert_true(tester,(transform->get_transform_id(transform) == 3),"transform id"); + transform->create_transform_attribute_iterator(transform, &attributes, TRUE); + loopi = 0; + while (attributes->has_next(attributes)) + { + transform_attribute_t *attribute; + attributes->current(attributes, (void**)&attribute); + if (loopi == 0) + { + u_int8_t value[] = {0x05, 0x00}; + chunk_t attribute_value; + tester->assert_true(tester,(attribute->get_attribute_type(attribute) == 1),"attribute 1 type"); + attribute_value = attribute->get_value(attribute); + tester->assert_false(tester,(memcmp(&value, attribute_value.ptr, attribute_value.len)),"attribute 1 value"); + } + if (loopi == 1) + { + u_int8_t value[] = {0x01, 0x02, 0x03, 0x04}; + chunk_t attribute_value; + tester->assert_true(tester,(attribute->get_attribute_type(attribute) == 3),"attribute 2 type"); + attribute_value = attribute->get_value(attribute); + tester->assert_false(tester,(memcmp(&value, attribute_value.ptr, attribute_value.len)),"attribute 2 value"); + } + loopi++; + } + attributes->destroy(attributes); + } + transforms->destroy(transforms); + } + proposals->destroy(proposals); + + sa_payload->destroy(sa_payload); } + +/* + * Described in Header + */ +void test_parser_with_nonce_payload(tester_t *tester) +{ + parser_t *parser; + nonce_payload_t *nonce_payload; + status_t status; + chunk_t nonce_chunk, result; + + + u_int8_t nonce_bytes[] = { + 0x00,0x00,0x00,0x14, /* payload header */ + 0x00,0x01,0x02,0x03, /* 16 Byte nonce */ + 0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x2B, + 0x0C,0x0D,0x0E,0x0F + }; + + nonce_chunk.ptr = nonce_bytes; + nonce_chunk.len = sizeof(nonce_bytes); + + + parser = parser_create(nonce_chunk); + tester->assert_true(tester,(parser != NULL), "parser create check"); + status = parser->parse_payload(parser, NONCE, (payload_t**)&nonce_payload); + tester->assert_true(tester,(status == SUCCESS),"parse_payload call check"); + tester->assert_true(tester,(parser->destroy(parser) == SUCCESS), "parser destroy call check"); + + if (status != SUCCESS) + { + return; + } + + nonce_payload->get_nonce(nonce_payload, &result); + + tester->assert_true(tester,(result.len == 16), "parsed nonce lenght"); + tester->assert_false(tester,(memcmp(nonce_bytes + 4, result.ptr, result.len)), "parsed nonce data"); + + + + + nonce_payload->destroy(nonce_payload); +} diff --git a/Source/charon/testcases/parser_test.h b/Source/charon/testcases/parser_test.h index 0d9e70d65..a59896b1b 100644 --- a/Source/charon/testcases/parser_test.h +++ b/Source/charon/testcases/parser_test.h @@ -29,6 +29,6 @@ void test_parser_with_header_payload(tester_t *tester); void test_parser_with_sa_payload(tester_t *tester); - +void test_parser_with_nonce_payload(tester_t *tester); #endif /*PARSER_TEST_H_*/