summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/ike_sa_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa/ike_sa_manager.c')
-rw-r--r--src/libcharon/sa/ike_sa_manager.c48
1 files changed, 14 insertions, 34 deletions
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index 8e68e7bee..bdabc59b5 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -384,11 +384,6 @@ struct private_ike_sa_manager_t {
rng_t *rng;
/**
- * SHA1 hasher for IKE_SA_INIT retransmit detection
- */
- hasher_t *hasher;
-
- /**
* reuse existing IKE_SAs in checkout_by_config
*/
bool reuse_ikesa;
@@ -962,49 +957,39 @@ static u_int64_t get_spi(private_ike_sa_manager_t *this)
*
* @returns TRUE on success
*/
-static bool get_init_hash(private_ike_sa_manager_t *this, message_t *message,
- chunk_t *hash)
+static bool get_init_hash(hasher_t *hasher, message_t *message, chunk_t *hash)
{
host_t *src;
- if (!this->hasher)
- { /* this might be the case when flush() has been called */
- return FALSE;
- }
if (message->get_first_payload_type(message) == PLV1_FRAGMENT)
{ /* only hash the source IP, port and SPI for fragmented init messages */
u_int16_t port;
u_int64_t spi;
src = message->get_source(message);
- if (!this->hasher->allocate_hash(this->hasher,
- src->get_address(src), NULL))
+ if (!hasher->allocate_hash(hasher, src->get_address(src), NULL))
{
return FALSE;
}
port = src->get_port(src);
- if (!this->hasher->allocate_hash(this->hasher,
- chunk_from_thing(port), NULL))
+ if (!hasher->allocate_hash(hasher, chunk_from_thing(port), NULL))
{
return FALSE;
}
spi = message->get_initiator_spi(message);
- return this->hasher->allocate_hash(this->hasher,
- chunk_from_thing(spi), hash);
+ return hasher->allocate_hash(hasher, chunk_from_thing(spi), hash);
}
if (message->get_exchange_type(message) == ID_PROT)
{ /* include the source for Main Mode as the hash will be the same if
* SPIs are reused by two initiators that use the same proposal */
src = message->get_source(message);
- if (!this->hasher->allocate_hash(this->hasher,
- src->get_address(src), NULL))
+ if (!hasher->allocate_hash(hasher, src->get_address(src), NULL))
{
return FALSE;
}
}
- return this->hasher->allocate_hash(this->hasher,
- message->get_packet_data(message), hash);
+ return hasher->allocate_hash(hasher, message->get_packet_data(message), hash);
}
/**
@@ -1227,15 +1212,19 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*,
if (is_init)
{
+ hasher_t *hasher;
u_int64_t our_spi;
chunk_t hash;
- if (!get_init_hash(this, message, &hash))
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher || !get_init_hash(hasher, message, &hash))
{
DBG1(DBG_MGR, "ignoring message, failed to hash message");
+ DESTROY_IF(hasher);
id->destroy(id);
return NULL;
}
+ hasher->destroy(hasher);
/* ensure this is not a retransmit of an already handled init message */
switch (check_and_put_init_hash(this, hash, &our_spi))
@@ -1313,8 +1302,9 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*,
ike_id = entry->ike_sa->get_id(entry->ike_sa);
entry->checked_out = TRUE;
- if (message->get_first_payload_type(message) != PLV1_FRAGMENT)
- {
+ if (message->get_first_payload_type(message) != PLV1_FRAGMENT &&
+ message->get_first_payload_type(message) != PLV2_FRAGMENT)
+ { /* TODO-FRAG: this fails if there are unencrypted payloads */
entry->processing = get_message_id_or_hash(message);
}
if (ike_id->get_responder_spi(ike_id) == 0)
@@ -2058,8 +2048,6 @@ METHOD(ike_sa_manager_t, flush, void,
this->rng->destroy(this->rng);
this->rng = NULL;
- this->hasher->destroy(this->hasher);
- this->hasher = NULL;
}
METHOD(ike_sa_manager_t, destroy, void,
@@ -2134,18 +2122,10 @@ ike_sa_manager_t *ike_sa_manager_create()
},
);
- this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (this->hasher == NULL)
- {
- DBG1(DBG_MGR, "manager initialization failed, no hasher supported");
- free(this);
- return NULL;
- }
this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
if (this->rng == NULL)
{
DBG1(DBG_MGR, "manager initialization failed, no RNG supported");
- this->hasher->destroy(this->hasher);
free(this);
return NULL;
}