/**
* Check if the given transform type is already in the set
*/
-static bool contains_type(private_proposal_t *this, transform_type_t type)
+static bool contains_type(array_t *types, transform_type_t type)
{
- return array_bsearch(this->types, &type, type_find, NULL) != -1;
+ return array_bsearch(types, &type, type_find, NULL) != -1;
}
/**
* Add the given transform type to the set
*/
-static void add_type(private_proposal_t *this, transform_type_t type)
+static void add_type(array_t *types, transform_type_t type)
{
- if (!contains_type(this, type))
+ if (!contains_type(types, type))
{
- array_insert(this->types, ARRAY_TAIL, &type);
- array_sort(this->types, type_sort, NULL);
+ array_insert(types, ARRAY_TAIL, &type);
+ array_sort(types, type_sort, NULL);
}
}
+/**
+ * Merge two sets of transform types into a new array
+ */
+static array_t *merge_types(private_proposal_t *this, private_proposal_t *other)
+{
+ array_t *types;
+ transform_type_t type;
+ int i, count;
+
+ count = max(array_count(this->types), array_count(other->types));
+ types = array_create(sizeof(transform_type_t), count);
+
+ for (i = 0; i < count; i++)
+ {
+ if (array_get(this->types, i, &type))
+ {
+ add_type(types, type);
+ }
+ if (array_get(other->types, i, &type))
+ {
+ add_type(types, type);
+ }
+ }
+ return types;
+}
+
/**
* Remove the given transform type from the set
*/
};
array_insert(this->transforms, ARRAY_TAIL, &entry);
- add_type(this, type);
+ add_type(this->types, type);
}
CALLBACK(alg_filter, bool,
bool private)
{
proposal_t *selected;
+ transform_type_t type;
+ array_t *types;
+ int i;
DBG2(DBG_CFG, "selecting proposal:");
{
selected = proposal_create(this->protocol, this->number);
selected->set_spi(selected, this->spi);
-
}
- if (!select_algo(this, other, selected, ENCRYPTION_ALGORITHM, private) ||
- !select_algo(this, other, selected, PSEUDO_RANDOM_FUNCTION, private) ||
- !select_algo(this, other, selected, INTEGRITY_ALGORITHM, private) ||
- !select_algo(this, other, selected, DIFFIE_HELLMAN_GROUP, private) ||
- !select_algo(this, other, selected, EXTENDED_SEQUENCE_NUMBERS, private))
+ types = merge_types(this, (private_proposal_t*)other);
+ for (i = 0; i < array_count(types); i++)
{
- selected->destroy(selected);
- return NULL;
+ array_get(types, i, &type);
+ if (!select_algo(this, other, selected, type, private))
+ {
+ selected->destroy(selected);
+ array_destroy(types);
+ return NULL;
+ }
}
+ array_destroy(types);
DBG2(DBG_CFG, " proposal matches");
return selected;
proposal->destroy(proposal);
proposal = proposal_create_from_string(PROTO_IKE,
- "aes128-sha256-modp3072-ecp256");
+ "aes128-sha256-ecp256");
proposal->add_algorithm(proposal, 242, 42, 128);
proposal->add_algorithm(proposal, 243, 1, 0);
- assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072/ECP_256/UNKNOWN_242_42_128/UNKNOWN_243_1");
+ assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256/UNKNOWN_242_42_128/UNKNOWN_243_1");
proposal->destroy(proposal);
}
END_TEST
+START_TEST(test_unknown_transform_types_select_fail)
+{
+ proposal_t *self, *other, *selected;
+
+ self = proposal_create_from_string(PROTO_IKE, "aes128-sha256-ecp256");
+ other = proposal_create_from_string(PROTO_IKE, "aes128-sha256-ecp256");
+ other->add_algorithm(other, 242, 42, 0);
+
+ selected = self->select(self, other, TRUE, FALSE);
+ ck_assert(!selected);
+ other->destroy(other);
+ self->destroy(self);
+}
+END_TEST
+
+START_TEST(test_unknown_transform_types_select_fail_subtype)
+{
+ proposal_t *self, *other, *selected;
+
+ self = proposal_create_from_string(PROTO_IKE, "aes128-sha256-ecp256");
+ self->add_algorithm(self, 242, 8, 0);
+ other = proposal_create_from_string(PROTO_IKE, "aes128-sha256-ecp256");
+ other->add_algorithm(other, 242, 42, 0);
+
+ selected = self->select(self, other, TRUE, FALSE);
+ ck_assert(!selected);
+ other->destroy(other);
+ self->destroy(self);
+}
+END_TEST
+
+START_TEST(test_unknown_transform_types_select_success)
+{
+ proposal_t *self, *other, *selected;
+
+ self = proposal_create_from_string(PROTO_IKE, "aes128-sha256-ecp256");
+ self->add_algorithm(self, 242, 42, 128);
+ other = proposal_create_from_string(PROTO_IKE, "aes128-sha256-ecp256");
+ other->add_algorithm(other, 242, 42, 128);
+ other->add_algorithm(other, 242, 1, 0);
+
+ selected = self->select(self, other, TRUE, FALSE);
+ ck_assert(selected);
+ assert_proposal_eq(selected, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256/UNKNOWN_242_42_128");
+ selected->destroy(selected);
+ other->destroy(other);
+ self->destroy(self);
+}
+END_TEST
+
+
+
Suite *proposal_suite_create()
{
Suite *s;
tc = tcase_create("unknown transform types");
tcase_add_test(tc, test_unknown_transform_types_print);
+ tcase_add_test(tc, test_unknown_transform_types_select_fail);
+ tcase_add_test(tc, test_unknown_transform_types_select_fail_subtype);
+ tcase_add_test(tc, test_unknown_transform_types_select_success);
suite_add_tcase(s, tc);
return s;