mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-03 00:00:24 -04:00
proposal: Prevent selection of duplicate key exchange methods
All additional (and the initial) key exchanges must use a different method.
This commit is contained in:
parent
1d5e921911
commit
012d99ecf4
@ -21,6 +21,7 @@
|
|||||||
#include "proposal.h"
|
#include "proposal.h"
|
||||||
|
|
||||||
#include <collections/array.h>
|
#include <collections/array.h>
|
||||||
|
#include <collections/hashtable.h>
|
||||||
#include <utils/identification.h>
|
#include <utils/identification.h>
|
||||||
|
|
||||||
#include <crypto/transform.h>
|
#include <crypto/transform.h>
|
||||||
@ -316,7 +317,7 @@ METHOD(proposal_t, promote_transform, bool,
|
|||||||
*/
|
*/
|
||||||
static bool select_algo(private_proposal_t *this, proposal_t *other,
|
static bool select_algo(private_proposal_t *this, proposal_t *other,
|
||||||
transform_type_t type, proposal_selection_flag_t flags,
|
transform_type_t type, proposal_selection_flag_t flags,
|
||||||
bool log, uint16_t *alg, uint16_t *ks)
|
hashtable_t *kes, bool log, uint16_t *alg, uint16_t *ks)
|
||||||
{
|
{
|
||||||
enumerator_t *e1, *e2;
|
enumerator_t *e1, *e2;
|
||||||
uint16_t alg1, alg2, ks1, ks2;
|
uint16_t alg1, alg2, ks1, ks2;
|
||||||
@ -359,9 +360,13 @@ static bool select_algo(private_proposal_t *this, proposal_t *other,
|
|||||||
|
|
||||||
e1->destroy(e1);
|
e1->destroy(e1);
|
||||||
e1 = create_enumerator(this, type);
|
e1 = create_enumerator(this, type);
|
||||||
/* compare algs, order of algs in "first" is preferred */
|
/* compare algs, order of algs in "e1" is preferred */
|
||||||
while (!found && e1->enumerate(e1, &alg1, &ks1))
|
while (!found && e1->enumerate(e1, &alg1, &ks1))
|
||||||
{
|
{
|
||||||
|
if (is_ke_transform(type) && kes->get(kes, (void*)(uintptr_t)alg1))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
e2->destroy(e2);
|
e2->destroy(e2);
|
||||||
e2 = other->create_enumerator(other, type);
|
e2 = other->create_enumerator(other, type);
|
||||||
while (e2->enumerate(e2, &alg2, &ks2))
|
while (e2->enumerate(e2, &alg2, &ks2))
|
||||||
@ -390,6 +395,23 @@ static bool select_algo(private_proposal_t *this, proposal_t *other,
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash an algorithm identifier
|
||||||
|
*/
|
||||||
|
static u_int hash_alg(const void *key)
|
||||||
|
{
|
||||||
|
uint16_t alg = (uint16_t)(uintptr_t)key;
|
||||||
|
return chunk_hash(chunk_from_thing(alg));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two algorithm identifiers
|
||||||
|
*/
|
||||||
|
static bool equals_alg(const void *key, const void *other_key)
|
||||||
|
{
|
||||||
|
return (uint16_t)(uintptr_t)key == (uint16_t)(uintptr_t)other_key;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select algorithms from the given proposals, if selected is given, the result
|
* Select algorithms from the given proposals, if selected is given, the result
|
||||||
* is stored there and errors are logged.
|
* is stored there and errors are logged.
|
||||||
@ -398,10 +420,13 @@ static bool select_algos(private_proposal_t *this, proposal_t *other,
|
|||||||
proposal_t *selected, proposal_selection_flag_t flags)
|
proposal_t *selected, proposal_selection_flag_t flags)
|
||||||
{
|
{
|
||||||
transform_type_t type;
|
transform_type_t type;
|
||||||
|
hashtable_t *kes;
|
||||||
array_t *types;
|
array_t *types;
|
||||||
bool skip_integrity = FALSE;
|
bool skip_integrity = FALSE;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
kes = hashtable_create(hash_alg, equals_alg, 8);
|
||||||
|
|
||||||
types = merge_types(this, (private_proposal_t*)other);
|
types = merge_types(this, (private_proposal_t*)other);
|
||||||
for (i = 0; i < array_count(types); i++)
|
for (i = 0; i < array_count(types); i++)
|
||||||
{
|
{
|
||||||
@ -416,7 +441,8 @@ static bool select_algos(private_proposal_t *this, proposal_t *other,
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (select_algo(this, other, type, flags, selected != NULL, &alg, &ks))
|
if (select_algo(this, other, type, flags, kes, selected != NULL,
|
||||||
|
&alg, &ks))
|
||||||
{
|
{
|
||||||
if (alg == 0 && type != EXTENDED_SEQUENCE_NUMBERS)
|
if (alg == 0 && type != EXTENDED_SEQUENCE_NUMBERS)
|
||||||
{ /* 0 is "valid" for extended sequence numbers, for other
|
{ /* 0 is "valid" for extended sequence numbers, for other
|
||||||
@ -427,6 +453,10 @@ static bool select_algos(private_proposal_t *this, proposal_t *other,
|
|||||||
{
|
{
|
||||||
selected->add_algorithm(selected, type, alg, ks);
|
selected->add_algorithm(selected, type, alg, ks);
|
||||||
}
|
}
|
||||||
|
if (is_ke_transform(type))
|
||||||
|
{
|
||||||
|
kes->put(kes, (void*)(uintptr_t)alg, (void*)(uintptr_t)alg);
|
||||||
|
}
|
||||||
if (type == ENCRYPTION_ALGORITHM &&
|
if (type == ENCRYPTION_ALGORITHM &&
|
||||||
encryption_algorithm_is_aead(alg))
|
encryption_algorithm_is_aead(alg))
|
||||||
{
|
{
|
||||||
@ -442,10 +472,12 @@ static bool select_algos(private_proposal_t *this, proposal_t *other,
|
|||||||
type);
|
type);
|
||||||
}
|
}
|
||||||
array_destroy(types);
|
array_destroy(types);
|
||||||
|
kes->destroy(kes);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
array_destroy(types);
|
array_destroy(types);
|
||||||
|
kes->destroy(kes);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +143,28 @@ static struct {
|
|||||||
{ PROTO_IKE, "aes128-sha256-modp3072", "aes128-sha256-modp3072", "aes128-sha256-modp3072" },
|
{ PROTO_IKE, "aes128-sha256-modp3072", "aes128-sha256-modp3072", "aes128-sha256-modp3072" },
|
||||||
{ PROTO_IKE, "aes128-sha256-modp3072", "aes128-sha256-modp3072-none", "aes128-sha256-modp3072" },
|
{ PROTO_IKE, "aes128-sha256-modp3072", "aes128-sha256-modp3072-none", "aes128-sha256-modp3072" },
|
||||||
{ PROTO_IKE, "aes128-sha256-modp3072-none", "aes128-sha256-modp3072", "aes128-sha256-modp3072" },
|
{ PROTO_IKE, "aes128-sha256-modp3072-none", "aes128-sha256-modp3072", "aes128-sha256-modp3072" },
|
||||||
|
{ PROTO_IKE, "aes128-sha256-modp3072-ke1_modp3072",
|
||||||
|
"aes128-sha256-modp3072-ke1_modp3072", NULL },
|
||||||
|
{ PROTO_IKE, "aes128-sha256-modp3072-ecp256-ecp384-ke1_modp3072-ke1_ecp256-ke1_ecp384-ke2_modp3072-ke2_ecp256-ke2_ecp384",
|
||||||
|
"aes128-sha256-modp3072-ecp256-ecp384-ke1_modp3072-ke1_ecp256-ke1_ecp384-ke2_modp3072-ke2_ecp256-ke2_ecp384",
|
||||||
|
"aes128-sha256-modp3072-ke1_ecp256-ke2_ecp384" },
|
||||||
|
{ PROTO_IKE, "aes128-sha256-modp3072-ke1_modp3072-ke1_none",
|
||||||
|
"aes128-sha256-modp3072-ke1_modp3072-ke1_none",
|
||||||
|
"aes128-sha256-modp3072" },
|
||||||
|
{ PROTO_IKE, "aes128-sha256-modp3072-ke1_modp3072-ke1_none-ke2_modp3072-ke2_none",
|
||||||
|
"aes128-sha256-modp3072-ke1_modp3072-ke1_none-ke2_modp3072-ke2_none",
|
||||||
|
"aes128-sha256-modp3072" },
|
||||||
|
{ PROTO_IKE, "aes128-sha256-modp3072-ke1_modp3072-ke1_ecp256",
|
||||||
|
"aes128-sha256-modp3072-ke1_modp3072-ke1_ecp256",
|
||||||
|
"aes128-sha256-modp3072-ke1_ecp256" },
|
||||||
|
{ PROTO_IKE, "aes128-sha256-modp3072-ke1_modp3072-ke1_ecp256",
|
||||||
|
"aes128-sha256-modp3072-ke1_ecp256",
|
||||||
|
"aes128-sha256-modp3072-ke1_ecp256" },
|
||||||
|
{ PROTO_IKE, "aes128-sha256-modp3072-ke1_ecp256",
|
||||||
|
"aes128-sha256-modp3072-ke1_modp3072-ke1_ecp256",
|
||||||
|
"aes128-sha256-modp3072-ke1_ecp256" },
|
||||||
|
{ PROTO_IKE, "aes128-sha256-ecp256-ke1_modp3072",
|
||||||
|
"aes128-sha256-modp3072-ecp256-ke1_ecp256-ke2_ecp384", NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
START_TEST(test_select)
|
START_TEST(test_select)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user