proposal: Generalize KE methods
This commit is contained in:
@@ -797,13 +797,13 @@ static linked_list_t *get_proposals(private_quick_mode_t *this,
|
|||||||
{
|
{
|
||||||
if (group != KE_NONE)
|
if (group != KE_NONE)
|
||||||
{
|
{
|
||||||
if (!proposal->has_ke_method(proposal, group))
|
if (!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, group))
|
||||||
{
|
{
|
||||||
list->remove_at(list, enumerator);
|
list->remove_at(list, enumerator);
|
||||||
proposal->destroy(proposal);
|
proposal->destroy(proposal);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
proposal->promote_ke_method(proposal, group);
|
proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, group);
|
||||||
}
|
}
|
||||||
proposal->set_spi(proposal, this->spi_i);
|
proposal->set_spi(proposal, this->spi_i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -328,7 +328,8 @@ static bool update_and_check_proposals(private_child_create_t *this)
|
|||||||
if (this->dh_group != KE_NONE)
|
if (this->dh_group != KE_NONE)
|
||||||
{ /* proposals that don't contain the selected group are
|
{ /* proposals that don't contain the selected group are
|
||||||
* moved to the back */
|
* moved to the back */
|
||||||
if (!proposal->promote_ke_method(proposal, this->dh_group))
|
if (!proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
this->dh_group))
|
||||||
{
|
{
|
||||||
this->proposals->remove_at(this->proposals, enumerator);
|
this->proposals->remove_at(this->proposals, enumerator);
|
||||||
other_dh_groups->insert_last(other_dh_groups, proposal);
|
other_dh_groups->insert_last(other_dh_groups, proposal);
|
||||||
@@ -554,7 +555,8 @@ static status_t select_and_install(private_child_create_t *this,
|
|||||||
}
|
}
|
||||||
this->child_sa->set_proposal(this->child_sa, this->proposal);
|
this->child_sa->set_proposal(this->child_sa, this->proposal);
|
||||||
|
|
||||||
if (!this->proposal->has_ke_method(this->proposal, this->dh_group))
|
if (!this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
this->dh_group))
|
||||||
{
|
{
|
||||||
uint16_t group;
|
uint16_t group;
|
||||||
|
|
||||||
|
|||||||
@@ -333,7 +333,8 @@ static bool build_payloads(private_ike_init_t *this, message_t *message)
|
|||||||
proposal->set_spi(proposal, id->get_initiator_spi(id));
|
proposal->set_spi(proposal, id->get_initiator_spi(id));
|
||||||
}
|
}
|
||||||
/* move the selected DH group to the front of the proposal */
|
/* move the selected DH group to the front of the proposal */
|
||||||
if (!proposal->promote_ke_method(proposal, this->dh_group))
|
if (!proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
this->dh_group))
|
||||||
{ /* the proposal does not include the group, move to the back */
|
{ /* the proposal does not include the group, move to the back */
|
||||||
proposal_list->remove_at(proposal_list, enumerator);
|
proposal_list->remove_at(proposal_list, enumerator);
|
||||||
other_dh_groups->insert_last(other_dh_groups, proposal);
|
other_dh_groups->insert_last(other_dh_groups, proposal);
|
||||||
@@ -617,7 +618,8 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ke_payload && this->proposal &&
|
if (ke_payload && this->proposal &&
|
||||||
this->proposal->has_ke_method(this->proposal, this->dh_group))
|
this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
this->dh_group))
|
||||||
{
|
{
|
||||||
if (!this->initiator)
|
if (!this->initiator)
|
||||||
{
|
{
|
||||||
@@ -829,7 +831,8 @@ METHOD(task_t, build_r, status_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->dh == NULL ||
|
if (this->dh == NULL ||
|
||||||
!this->proposal->has_ke_method(this->proposal, this->dh_group))
|
!this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
this->dh_group))
|
||||||
{
|
{
|
||||||
uint16_t group;
|
uint16_t group;
|
||||||
|
|
||||||
@@ -1064,7 +1067,8 @@ METHOD(task_t, process_i, status_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->dh == NULL ||
|
if (this->dh == NULL ||
|
||||||
!this->proposal->has_ke_method(this->proposal, this->dh_group))
|
!this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
this->dh_group))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "peer DH group selection invalid");
|
DBG1(DBG_IKE, "peer DH group selection invalid");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
|
|||||||
@@ -252,34 +252,37 @@ METHOD(proposal_t, get_algorithm, bool,
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(proposal_t, has_ke_method, bool,
|
METHOD(proposal_t, has_transform, bool,
|
||||||
private_proposal_t *this, key_exchange_method_t ke)
|
private_proposal_t *this, transform_type_t type, uint16_t alg)
|
||||||
{
|
{
|
||||||
bool found = FALSE, any = FALSE;
|
bool found = FALSE, any = FALSE;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
uint16_t current;
|
uint16_t current;
|
||||||
|
|
||||||
enumerator = create_enumerator(this, KEY_EXCHANGE_METHOD);
|
enumerator = create_enumerator(this, type);
|
||||||
while (enumerator->enumerate(enumerator, ¤t, NULL))
|
while (enumerator->enumerate(enumerator, ¤t, NULL))
|
||||||
{
|
{
|
||||||
any = TRUE;
|
if (current)
|
||||||
if (current == ke)
|
|
||||||
{
|
{
|
||||||
found = TRUE;
|
any = TRUE;
|
||||||
break;
|
if (alg && current == alg)
|
||||||
|
{
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
if (!any && ke == KE_NONE)
|
if (!any && !alg)
|
||||||
{
|
{
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(proposal_t, promote_ke_method, bool,
|
METHOD(proposal_t, promote_transform, bool,
|
||||||
private_proposal_t *this, key_exchange_method_t method)
|
private_proposal_t *this, transform_type_t type, uint16_t alg)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
entry_t *entry;
|
entry_t *entry;
|
||||||
@@ -288,8 +291,8 @@ METHOD(proposal_t, promote_ke_method, bool,
|
|||||||
enumerator = array_create_enumerator(this->transforms);
|
enumerator = array_create_enumerator(this->transforms);
|
||||||
while (enumerator->enumerate(enumerator, &entry))
|
while (enumerator->enumerate(enumerator, &entry))
|
||||||
{
|
{
|
||||||
if (entry->type == KEY_EXCHANGE_METHOD &&
|
if (entry->type == type &&
|
||||||
entry->alg == method)
|
entry->alg == alg)
|
||||||
{
|
{
|
||||||
array_remove_at(this->transforms, enumerator);
|
array_remove_at(this->transforms, enumerator);
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
@@ -300,8 +303,8 @@ METHOD(proposal_t, promote_ke_method, bool,
|
|||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
entry_t entry = {
|
entry_t entry = {
|
||||||
.type = KEY_EXCHANGE_METHOD,
|
.type = type,
|
||||||
.alg = method,
|
.alg = alg,
|
||||||
};
|
};
|
||||||
array_insert(this->transforms, ARRAY_HEAD, &entry);
|
array_insert(this->transforms, ARRAY_HEAD, &entry);
|
||||||
}
|
}
|
||||||
@@ -943,8 +946,8 @@ proposal_t *proposal_create_v1(protocol_id_t protocol, uint8_t number,
|
|||||||
.add_algorithm = _add_algorithm,
|
.add_algorithm = _add_algorithm,
|
||||||
.create_enumerator = _create_enumerator,
|
.create_enumerator = _create_enumerator,
|
||||||
.get_algorithm = _get_algorithm,
|
.get_algorithm = _get_algorithm,
|
||||||
.has_ke_method = _has_ke_method,
|
.has_transform = _has_transform,
|
||||||
.promote_ke_method = _promote_ke_method,
|
.promote_transform = _promote_transform,
|
||||||
.select = _select_proposal,
|
.select = _select_proposal,
|
||||||
.matches = _matches,
|
.matches = _matches,
|
||||||
.get_protocol = _get_protocol,
|
.get_protocol = _get_protocol,
|
||||||
|
|||||||
@@ -110,21 +110,26 @@ struct proposal_t {
|
|||||||
uint16_t *alg, uint16_t *key_size);
|
uint16_t *alg, uint16_t *key_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the proposal has a specific key exchange method.
|
* Check if the proposal has a specific transform.
|
||||||
*
|
*
|
||||||
* @param method key exchange method to check for
|
* @param type kind of algorithm
|
||||||
|
* @param alg algorithm to check for (if 0, TRUE is returned if
|
||||||
|
* no transform of the given type is found)
|
||||||
* @return TRUE if algorithm included
|
* @return TRUE if algorithm included
|
||||||
*/
|
*/
|
||||||
bool (*has_ke_method)(proposal_t *this, key_exchange_method_t method);
|
bool (*has_transform)(proposal_t *this, transform_type_t type,
|
||||||
|
uint16_t alg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the given key exchange method to the front of the list if it was
|
* Move the given transform to the front of the list if it was contained in
|
||||||
* contained in the proposal.
|
* the proposal.
|
||||||
*
|
*
|
||||||
* @param method key exchange method to promote
|
* @param type kind of algorithm
|
||||||
|
* @param alg algorithm to promote
|
||||||
* @return TRUE if algorithm included
|
* @return TRUE if algorithm included
|
||||||
*/
|
*/
|
||||||
bool (*promote_ke_method)(proposal_t *this, key_exchange_method_t method);
|
bool (*promote_transform)(proposal_t *this, transform_type_t type,
|
||||||
|
uint16_t alg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two proposals and select a matching subset.
|
* Compare two proposals and select a matching subset.
|
||||||
|
|||||||
@@ -301,38 +301,89 @@ START_TEST(test_select_proposal)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST(test_promote_ke_method)
|
START_TEST(test_has_transform)
|
||||||
{
|
{
|
||||||
proposal_t *proposal;
|
proposal_t *proposal;
|
||||||
|
|
||||||
proposal = proposal_create_from_string(PROTO_IKE,
|
proposal = proposal_create_from_string(PROTO_IKE,
|
||||||
"aes128-sha256-modp3072-ecp256");
|
"aes128-sha256-modp3072-ecp256");
|
||||||
ck_assert(proposal->promote_ke_method(proposal, ECP_256_BIT));
|
ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
MODP_3072_BIT));
|
||||||
|
ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
ECP_256_BIT));
|
||||||
|
ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
MODP_2048_BIT));
|
||||||
|
proposal->destroy(proposal);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_has_transform_none)
|
||||||
|
{
|
||||||
|
proposal_t *proposal;
|
||||||
|
|
||||||
|
proposal = proposal_create_from_string(PROTO_ESP,
|
||||||
|
"aes128-sha256");
|
||||||
|
ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
KE_NONE));
|
||||||
|
proposal->destroy(proposal);
|
||||||
|
|
||||||
|
proposal = proposal_create_from_string(PROTO_ESP,
|
||||||
|
"aes128-sha256-none");
|
||||||
|
ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
KE_NONE));
|
||||||
|
proposal->destroy(proposal);
|
||||||
|
|
||||||
|
proposal = proposal_create_from_string(PROTO_ESP,
|
||||||
|
"aes128-sha256-modp3072");
|
||||||
|
ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
KE_NONE));
|
||||||
|
proposal->destroy(proposal);
|
||||||
|
|
||||||
|
/* while actually contained in the proposal, KE_NONE is 0 so we expect
|
||||||
|
* has_transform() to return FALSE if there are other algorithms */
|
||||||
|
proposal = proposal_create_from_string(PROTO_ESP,
|
||||||
|
"aes128-sha256-modp3072-none");
|
||||||
|
ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
KE_NONE));
|
||||||
|
proposal->destroy(proposal);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_promote_transform)
|
||||||
|
{
|
||||||
|
proposal_t *proposal;
|
||||||
|
|
||||||
|
proposal = proposal_create_from_string(PROTO_IKE,
|
||||||
|
"aes128-sha256-modp3072-ecp256");
|
||||||
|
ck_assert(proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
ECP_256_BIT));
|
||||||
assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256/MODP_3072");
|
assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256/MODP_3072");
|
||||||
proposal->destroy(proposal);
|
proposal->destroy(proposal);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST(test_promote_ke_method_already_front)
|
START_TEST(test_promote_transform_already_front)
|
||||||
{
|
{
|
||||||
proposal_t *proposal;
|
proposal_t *proposal;
|
||||||
|
|
||||||
proposal = proposal_create_from_string(PROTO_IKE,
|
proposal = proposal_create_from_string(PROTO_IKE,
|
||||||
"aes128-sha256-modp3072-ecp256");
|
"aes128-sha256-modp3072-ecp256");
|
||||||
ck_assert(proposal->promote_ke_method(proposal, MODP_3072_BIT));
|
ck_assert(proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
MODP_3072_BIT));
|
||||||
assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072/ECP_256");
|
assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072/ECP_256");
|
||||||
proposal->destroy(proposal);
|
proposal->destroy(proposal);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST(test_promote_ke_method_not_contained)
|
START_TEST(test_promote_transform_not_contained)
|
||||||
{
|
{
|
||||||
proposal_t *proposal;
|
proposal_t *proposal;
|
||||||
|
|
||||||
proposal = proposal_create_from_string(PROTO_IKE,
|
proposal = proposal_create_from_string(PROTO_IKE,
|
||||||
"aes128-sha256-modp3072-ecp256");
|
"aes128-sha256-modp3072-ecp256");
|
||||||
|
|
||||||
ck_assert(!proposal->promote_ke_method(proposal, MODP_2048_BIT));
|
ck_assert(!proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD,
|
||||||
|
MODP_2048_BIT));
|
||||||
assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072/ECP_256");
|
assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072/ECP_256");
|
||||||
proposal->destroy(proposal);
|
proposal->destroy(proposal);
|
||||||
}
|
}
|
||||||
@@ -505,10 +556,15 @@ Suite *proposal_suite_create()
|
|||||||
countof(select_proposal_data));
|
countof(select_proposal_data));
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("promote_ke_method");
|
tc = tcase_create("has_transform");
|
||||||
tcase_add_test(tc, test_promote_ke_method);
|
tcase_add_test(tc, test_has_transform);
|
||||||
tcase_add_test(tc, test_promote_ke_method_already_front);
|
tcase_add_test(tc, test_has_transform_none);
|
||||||
tcase_add_test(tc, test_promote_ke_method_not_contained);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
tc = tcase_create("promote_transform");
|
||||||
|
tcase_add_test(tc, test_promote_transform);
|
||||||
|
tcase_add_test(tc, test_promote_transform_already_front);
|
||||||
|
tcase_add_test(tc, test_promote_transform_not_contained);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("unknown transform types");
|
tc = tcase_create("unknown transform types");
|
||||||
|
|||||||
Reference in New Issue
Block a user