Merge branch 'tkm-fixes'
This fixes several issues with charon-tkm (e.g. nonce context ID leaks during rekey collisions).
This commit is contained in:
@@ -19,8 +19,6 @@
|
|||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
#include <threading/rwlock.h>
|
#include <threading/rwlock.h>
|
||||||
|
|
||||||
#define TKM_LIMIT 100
|
|
||||||
|
|
||||||
ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_ESA,
|
ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_ESA,
|
||||||
"NONCE_CONTEXT",
|
"NONCE_CONTEXT",
|
||||||
"DH_CONTEXT",
|
"DH_CONTEXT",
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
esa_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_ESA);
|
esa_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_ESA);
|
||||||
if (!tkm->sad->insert(tkm->sad, reqid, esa_id, local, peer, spi_rem,
|
if (!tkm->sad->insert(tkm->sad, esa_id, reqid, local, peer, spi_loc, spi_rem,
|
||||||
protocol))
|
protocol))
|
||||||
{
|
{
|
||||||
DBG1(DBG_KNL, "unable to add entry (%llu) to SAD", esa_id);
|
DBG1(DBG_KNL, "unable to add entry (%llu) to SAD", esa_id);
|
||||||
@@ -164,6 +164,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||||||
DBG1(DBG_KNL, "child SA (%llu, no PFS) creation failed", esa_id);
|
DBG1(DBG_KNL, "child SA (%llu, no PFS) creation failed", esa_id);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
tkm->chunk_map->remove(tkm->chunk_map, nonce_loc);
|
||||||
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nonce_loc_id);
|
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nonce_loc_id);
|
||||||
}
|
}
|
||||||
/* creation of subsequent child SA with PFS: nonce and dh context are set */
|
/* creation of subsequent child SA with PFS: nonce and dh context are set */
|
||||||
@@ -176,6 +177,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||||||
DBG1(DBG_KNL, "child SA (%llu) creation failed", esa_id);
|
DBG1(DBG_KNL, "child SA (%llu) creation failed", esa_id);
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
tkm->chunk_map->remove(tkm->chunk_map, nonce_loc);
|
||||||
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nonce_loc_id);
|
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nonce_loc_id);
|
||||||
}
|
}
|
||||||
if (ike_esa_select(esa_id) != TKM_OK)
|
if (ike_esa_select(esa_id) != TKM_OK)
|
||||||
@@ -217,11 +219,22 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
|
|||||||
private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst,
|
private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, u_int16_t cpi, mark_t mark)
|
u_int32_t spi, u_int8_t protocol, u_int16_t cpi, mark_t mark)
|
||||||
{
|
{
|
||||||
esa_id_type esa_id;
|
esa_id_type esa_id, other_esa_id;
|
||||||
|
|
||||||
esa_id = tkm->sad->get_esa_id(tkm->sad, src, dst, spi, protocol);
|
esa_id = tkm->sad->get_esa_id(tkm->sad, src, dst, spi, protocol);
|
||||||
if (esa_id)
|
if (esa_id)
|
||||||
{
|
{
|
||||||
|
other_esa_id = tkm->sad->get_other_esa_id(tkm->sad, esa_id);
|
||||||
|
if (other_esa_id)
|
||||||
|
{
|
||||||
|
DBG1(DBG_KNL, "selecting child SA (esa: %llu)", other_esa_id);
|
||||||
|
if (ike_esa_select(other_esa_id) != TKM_OK)
|
||||||
|
{
|
||||||
|
DBG1(DBG_KNL, "error selecting other child SA (esa: %llu)",
|
||||||
|
other_esa_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DBG1(DBG_KNL, "deleting child SA (esa: %llu, spi: %x)", esa_id,
|
DBG1(DBG_KNL, "deleting child SA (esa: %llu, spi: %x)", esa_id,
|
||||||
ntohl(spi));
|
ntohl(spi));
|
||||||
if (ike_esa_reset(esa_id) != TKM_OK)
|
if (ike_esa_reset(esa_id) != TKM_OK)
|
||||||
|
|||||||
@@ -72,9 +72,14 @@ struct sad_entry_t {
|
|||||||
host_t *dst;
|
host_t *dst;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SPI of CHILD SA.
|
* Local SPI of CHILD SA.
|
||||||
*/
|
*/
|
||||||
u_int32_t spi;
|
u_int32_t spi_loc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remote SPI of CHILD SA.
|
||||||
|
*/
|
||||||
|
u_int32_t spi_rem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protocol of CHILD SA (ESP/AH).
|
* Protocol of CHILD SA (ESP/AH).
|
||||||
@@ -97,7 +102,7 @@ static void sad_entry_destroy(sad_entry_t *entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a list entry with given src, dst, spi and proto values.
|
* Find a list entry with given src, dst, (remote) spi and proto values.
|
||||||
*/
|
*/
|
||||||
static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src,
|
static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src,
|
||||||
const host_t * const dst, const u_int32_t * const spi,
|
const host_t * const dst, const u_int32_t * const spi,
|
||||||
@@ -110,7 +115,7 @@ static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src,
|
|||||||
|
|
||||||
return src->ip_equals(entry->src, (host_t *)src) &&
|
return src->ip_equals(entry->src, (host_t *)src) &&
|
||||||
dst->ip_equals(entry->dst, (host_t *)dst) &&
|
dst->ip_equals(entry->dst, (host_t *)dst) &&
|
||||||
entry->spi == *spi && entry->proto == *proto;
|
entry->spi_rem == *spi && entry->proto == *proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -121,9 +126,29 @@ static bool sad_entry_match_dst(sad_entry_t * const entry,
|
|||||||
const u_int32_t * const spi,
|
const u_int32_t * const spi,
|
||||||
const u_int8_t * const proto)
|
const u_int8_t * const proto)
|
||||||
{
|
{
|
||||||
return entry->reqid == *reqid &&
|
return entry->reqid == *reqid &&
|
||||||
entry->spi == *spi &&
|
entry->spi_rem == *spi &&
|
||||||
entry->proto == *proto;
|
entry->proto == *proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a list entry with given esa id.
|
||||||
|
*/
|
||||||
|
static bool sad_entry_match_esa_id(sad_entry_t * const entry,
|
||||||
|
const esa_id_type * const esa_id)
|
||||||
|
{
|
||||||
|
return entry->esa_id == *esa_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a list entry with given reqid and different esa id.
|
||||||
|
*/
|
||||||
|
static bool sad_entry_match_other_esa(sad_entry_t * const entry,
|
||||||
|
const esa_id_type * const esa_id,
|
||||||
|
const u_int32_t * const reqid)
|
||||||
|
{
|
||||||
|
return entry->reqid == *reqid &&
|
||||||
|
entry->esa_id != *esa_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,13 +165,15 @@ static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
|
|||||||
left->reqid == right->reqid &&
|
left->reqid == right->reqid &&
|
||||||
left->src->ip_equals(left->src, right->src) &&
|
left->src->ip_equals(left->src, right->src) &&
|
||||||
left->dst->ip_equals(left->dst, right->dst) &&
|
left->dst->ip_equals(left->dst, right->dst) &&
|
||||||
left->spi == right->spi && left->proto == right->proto;
|
left->spi_loc == right->spi_loc &&
|
||||||
|
left->spi_rem == right->spi_rem &&
|
||||||
|
left->proto == right->proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(tkm_kernel_sad_t, insert, bool,
|
METHOD(tkm_kernel_sad_t, insert, bool,
|
||||||
private_tkm_kernel_sad_t * const this, const esa_id_type esa_id,
|
private_tkm_kernel_sad_t * const this, const esa_id_type esa_id,
|
||||||
const u_int32_t reqid, const host_t * const src, const host_t * const dst,
|
const u_int32_t reqid, const host_t * const src, const host_t * const dst,
|
||||||
const u_int32_t spi, const u_int8_t proto)
|
const u_int32_t spi_loc, const u_int32_t spi_rem, const u_int8_t proto)
|
||||||
{
|
{
|
||||||
status_t result;
|
status_t result;
|
||||||
sad_entry_t *new_entry;
|
sad_entry_t *new_entry;
|
||||||
@@ -156,7 +183,8 @@ METHOD(tkm_kernel_sad_t, insert, bool,
|
|||||||
.reqid = reqid,
|
.reqid = reqid,
|
||||||
.src = (host_t *)src,
|
.src = (host_t *)src,
|
||||||
.dst = (host_t *)dst,
|
.dst = (host_t *)dst,
|
||||||
.spi = spi,
|
.spi_loc = spi_loc,
|
||||||
|
.spi_rem = spi_rem,
|
||||||
.proto = proto,
|
.proto = proto,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -167,8 +195,8 @@ METHOD(tkm_kernel_sad_t, insert, bool,
|
|||||||
if (result == NOT_FOUND)
|
if (result == NOT_FOUND)
|
||||||
{
|
{
|
||||||
DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, reqid: %u, src: %H, "
|
DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, reqid: %u, src: %H, "
|
||||||
"dst: %H, spi: %x, proto: %u)", esa_id, reqid, src, dst,
|
"dst: %H, spi_loc: %x, spi_rem: %x,proto: %u)", esa_id, reqid, src,
|
||||||
ntohl(spi), proto);
|
dst, ntohl(spi_loc), ntohl(spi_rem), proto);
|
||||||
new_entry->src = src->clone((host_t *)src);
|
new_entry->src = src->clone((host_t *)src);
|
||||||
new_entry->dst = dst->clone((host_t *)dst);
|
new_entry->dst = dst->clone((host_t *)dst);
|
||||||
this->data->insert_last(this->data, new_entry);
|
this->data->insert_last(this->data, new_entry);
|
||||||
@@ -209,6 +237,42 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(tkm_kernel_sad_t, get_other_esa_id, esa_id_type,
|
||||||
|
private_tkm_kernel_sad_t * const this, const esa_id_type esa_id)
|
||||||
|
{
|
||||||
|
esa_id_type id = 0;
|
||||||
|
sad_entry_t *entry = NULL;
|
||||||
|
u_int32_t reqid;
|
||||||
|
status_t res;
|
||||||
|
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
|
res = this->data->find_first(this->data,
|
||||||
|
(linked_list_match_t)sad_entry_match_esa_id,
|
||||||
|
(void**)&entry, &esa_id);
|
||||||
|
if (res == SUCCESS && entry)
|
||||||
|
{
|
||||||
|
reqid = entry->reqid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG3(DBG_KNL, "no SAD entry found for ESA id %llu", esa_id);
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = this->data->find_first(this->data,
|
||||||
|
(linked_list_match_t)sad_entry_match_other_esa,
|
||||||
|
(void**)&entry, &esa_id, &reqid);
|
||||||
|
if (res == SUCCESS && entry)
|
||||||
|
{
|
||||||
|
id = entry->esa_id;
|
||||||
|
DBG3(DBG_KNL, "returning ESA id %llu of other SAD entry with reqid %u",
|
||||||
|
id, reqid);
|
||||||
|
}
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(tkm_kernel_sad_t, get_dst_host, host_t *,
|
METHOD(tkm_kernel_sad_t, get_dst_host, host_t *,
|
||||||
private_tkm_kernel_sad_t * const this, const u_int32_t reqid,
|
private_tkm_kernel_sad_t * const this, const u_int32_t reqid,
|
||||||
const u_int32_t spi, const u_int8_t proto)
|
const u_int32_t spi, const u_int8_t proto)
|
||||||
@@ -289,6 +353,7 @@ tkm_kernel_sad_t *tkm_kernel_sad_create()
|
|||||||
.public = {
|
.public = {
|
||||||
.insert = _insert,
|
.insert = _insert,
|
||||||
.get_esa_id = _get_esa_id,
|
.get_esa_id = _get_esa_id,
|
||||||
|
.get_other_esa_id = _get_other_esa_id,
|
||||||
.get_dst_host = _get_dst_host,
|
.get_dst_host = _get_dst_host,
|
||||||
.remove = __remove,
|
.remove = __remove,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
|
|||||||
@@ -40,21 +40,22 @@ struct tkm_kernel_sad_t {
|
|||||||
* @param reqid reqid of the SA
|
* @param reqid reqid of the SA
|
||||||
* @param src source address of CHILD SA
|
* @param src source address of CHILD SA
|
||||||
* @param dst destination address of CHILD SA
|
* @param dst destination address of CHILD SA
|
||||||
* @param spi SPI of CHILD SA
|
* @param spi_loc Local SPI of CHILD SA
|
||||||
|
* @param spi_rem Remote SPI of CHILD SA
|
||||||
* @param proto protocol of CHILD SA (ESP/AH)
|
* @param proto protocol of CHILD SA (ESP/AH)
|
||||||
* @return TRUE if entry was inserted, FALSE otherwise
|
* @return TRUE if entry was inserted, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
bool (*insert)(tkm_kernel_sad_t * const this, const esa_id_type esa_id,
|
bool (*insert)(tkm_kernel_sad_t * const this, const esa_id_type esa_id,
|
||||||
const u_int32_t reqid, const host_t * const src,
|
const u_int32_t reqid, const host_t * const src,
|
||||||
const host_t * const dst, const u_int32_t spi,
|
const host_t * const dst, const u_int32_t spi_loc,
|
||||||
const u_int8_t proto);
|
const u_int32_t spi_rem, const u_int8_t proto);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ESA id for entry with given parameters.
|
* Get ESA id for entry with given parameters.
|
||||||
*
|
*
|
||||||
* @param src source address of CHILD SA
|
* @param src source address of CHILD SA
|
||||||
* @param dst destination address of CHILD SA
|
* @param dst destination address of CHILD SA
|
||||||
* @param spi SPI of CHILD SA
|
* @param spi Remote SPI of CHILD SA
|
||||||
* @param proto protocol of CHILD SA (ESP/AH)
|
* @param proto protocol of CHILD SA (ESP/AH)
|
||||||
* @return ESA id of entry if found, 0 otherwise
|
* @return ESA id of entry if found, 0 otherwise
|
||||||
*/
|
*/
|
||||||
@@ -62,11 +63,21 @@ struct tkm_kernel_sad_t {
|
|||||||
const host_t * const src, const host_t * const dst,
|
const host_t * const src, const host_t * const dst,
|
||||||
const u_int32_t spi, const u_int8_t proto);
|
const u_int32_t spi, const u_int8_t proto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get ESA id for entry associated with same security policy as the
|
||||||
|
* specified ESA.
|
||||||
|
*
|
||||||
|
* @param esa_id id of ESA identifying the security policy
|
||||||
|
* @return ESA id of entry if found, 0 otherwise
|
||||||
|
*/
|
||||||
|
esa_id_type (*get_other_esa_id)(tkm_kernel_sad_t * const this,
|
||||||
|
const esa_id_type esa_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get destination host for entry with given parameters.
|
* Get destination host for entry with given parameters.
|
||||||
*
|
*
|
||||||
* @param reqid reqid of CHILD SA
|
* @param reqid reqid of CHILD SA
|
||||||
* @param spi SPI of CHILD SA
|
* @param spi Remote SPI of CHILD SA
|
||||||
* @param proto protocol of CHILD SA (ESP/AH)
|
* @param proto protocol of CHILD SA (ESP/AH)
|
||||||
* @return destination host of entry if found, NULL otherwise
|
* @return destination host of entry if found, NULL otherwise
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
#include <encoding/payloads/auth_payload.h>
|
#include <encoding/payloads/auth_payload.h>
|
||||||
#include <utils/chunk.h>
|
#include <utils/chunk.h>
|
||||||
@@ -209,6 +211,13 @@ METHOD(listener_t, alert, bool,
|
|||||||
{
|
{
|
||||||
tkm_keymat_t *keymat;
|
tkm_keymat_t *keymat;
|
||||||
isa_id_type isa_id;
|
isa_id_type isa_id;
|
||||||
|
int is_first;
|
||||||
|
|
||||||
|
is_first = va_arg(args, int);
|
||||||
|
if (!is_first)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
keymat = (tkm_keymat_t*)ike_sa->get_keymat(ike_sa);
|
keymat = (tkm_keymat_t*)ike_sa->get_keymat(ike_sa);
|
||||||
isa_id = keymat->get_isa_id(keymat);
|
isa_id = keymat->get_isa_id(keymat);
|
||||||
|
|||||||
@@ -33,23 +33,32 @@ struct private_tkm_nonceg_t {
|
|||||||
tkm_nonceg_t public;
|
tkm_nonceg_t public;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context id.
|
* Nonce chunk.
|
||||||
*/
|
*/
|
||||||
nc_id_type context_id;
|
chunk_t nonce;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(nonce_gen_t, get_nonce, bool,
|
METHOD(nonce_gen_t, get_nonce, bool,
|
||||||
private_tkm_nonceg_t *this, size_t size, u_int8_t *buffer)
|
private_tkm_nonceg_t *this, size_t size, u_int8_t *buffer)
|
||||||
{
|
{
|
||||||
nonce_type nonce;
|
nonce_type nonce;
|
||||||
|
uint64_t nc_id;
|
||||||
|
|
||||||
if (ike_nc_create(this->context_id, size, &nonce) != TKM_OK)
|
nc_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_NONCE);
|
||||||
|
if (!nc_id)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ike_nc_create(nc_id, size, &nonce) != TKM_OK)
|
||||||
|
{
|
||||||
|
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nc_id);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(buffer, &nonce.data, size);
|
memcpy(buffer, &nonce.data, size);
|
||||||
|
this->nonce = chunk_clone(chunk_create(buffer, size));
|
||||||
|
tkm->chunk_map->insert(tkm->chunk_map, &this->nonce, nc_id);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,24 +66,28 @@ METHOD(nonce_gen_t, allocate_nonce, bool,
|
|||||||
private_tkm_nonceg_t *this, size_t size, chunk_t *chunk)
|
private_tkm_nonceg_t *this, size_t size, chunk_t *chunk)
|
||||||
{
|
{
|
||||||
*chunk = chunk_alloc(size);
|
*chunk = chunk_alloc(size);
|
||||||
if (get_nonce(this, chunk->len, chunk->ptr))
|
return get_nonce(this, chunk->len, chunk->ptr);
|
||||||
{
|
|
||||||
tkm->chunk_map->insert(tkm->chunk_map, chunk, this->context_id);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(nonce_gen_t, destroy, void,
|
METHOD(nonce_gen_t, destroy, void,
|
||||||
private_tkm_nonceg_t *this)
|
private_tkm_nonceg_t *this)
|
||||||
{
|
{
|
||||||
free(this);
|
uint64_t nc_id;
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(tkm_nonceg_t, get_id, nc_id_type,
|
nc_id = tkm->chunk_map->get_id(tkm->chunk_map, &this->nonce);
|
||||||
private_tkm_nonceg_t *this)
|
if (nc_id)
|
||||||
{
|
{
|
||||||
return this->context_id;
|
DBG1(DBG_IKE, "resetting stale nonce context %llu", nc_id);
|
||||||
|
|
||||||
|
if (ike_nc_reset(nc_id) != TKM_OK)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "failed to reset nonce context %llu", nc_id);
|
||||||
|
}
|
||||||
|
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nc_id);
|
||||||
|
tkm->chunk_map->remove(tkm->chunk_map, &this->nonce);
|
||||||
|
}
|
||||||
|
chunk_free(&this->nonce);
|
||||||
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -91,16 +104,8 @@ tkm_nonceg_t *tkm_nonceg_create()
|
|||||||
.allocate_nonce = _allocate_nonce,
|
.allocate_nonce = _allocate_nonce,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.get_id = _get_id,
|
|
||||||
},
|
},
|
||||||
.context_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_NONCE),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!this->context_id)
|
|
||||||
{
|
|
||||||
free(this);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,14 +36,6 @@ struct tkm_nonceg_t {
|
|||||||
* Implements nonce_gen_t.
|
* Implements nonce_gen_t.
|
||||||
*/
|
*/
|
||||||
nonce_gen_t nonce_gen;
|
nonce_gen_t nonce_gen;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get nonce context id.
|
|
||||||
*
|
|
||||||
* @return context id of this nonce generator.
|
|
||||||
*/
|
|
||||||
nc_id_type (*get_id)(tkm_nonceg_t * const this);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ START_TEST(test_insert)
|
|||||||
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
||||||
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
||||||
|
|
||||||
fail_unless(sad->insert(sad, 1, 2, addr, addr, 42, 50),
|
fail_unless(sad->insert(sad, 1, 2, addr, addr, 27, 42, 50),
|
||||||
"Error inserting SAD entry");
|
"Error inserting SAD entry");
|
||||||
|
|
||||||
sad->destroy(sad);
|
sad->destroy(sad);
|
||||||
@@ -47,9 +47,9 @@ START_TEST(test_insert_duplicate)
|
|||||||
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
||||||
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
||||||
|
|
||||||
fail_unless(sad->insert(sad, 1, 2, addr, addr, 42, 50),
|
fail_unless(sad->insert(sad, 1, 2, addr, addr, 27, 42, 50),
|
||||||
"Error inserting SAD entry");
|
"Error inserting SAD entry");
|
||||||
fail_if(sad->insert(sad, 1, 2, addr, addr, 42, 50),
|
fail_if(sad->insert(sad, 1, 2, addr, addr, 27, 42, 50),
|
||||||
"Expected error inserting duplicate entry");
|
"Expected error inserting duplicate entry");
|
||||||
|
|
||||||
sad->destroy(sad);
|
sad->destroy(sad);
|
||||||
@@ -61,7 +61,7 @@ START_TEST(test_get_esa_id)
|
|||||||
{
|
{
|
||||||
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
||||||
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
||||||
fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50),
|
fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
|
||||||
"Error inserting SAD entry");
|
"Error inserting SAD entry");
|
||||||
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
|
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
|
||||||
"Error getting esa id");
|
"Error getting esa id");
|
||||||
@@ -81,11 +81,42 @@ START_TEST(test_get_esa_id_nonexistent)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_get_other_esa_id)
|
||||||
|
{
|
||||||
|
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
||||||
|
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
||||||
|
fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
|
||||||
|
"Error inserting SAD entry");
|
||||||
|
fail_unless(sad->insert(sad, 24, 54, addr, addr, 27, 42, 50),
|
||||||
|
"Error inserting SAD entry");
|
||||||
|
fail_unless(sad->get_other_esa_id(sad, 23) == 24,
|
||||||
|
"Error getting other esa id");
|
||||||
|
sad->destroy(sad);
|
||||||
|
addr->destroy(addr);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_get_other_esa_id_nonexistent)
|
||||||
|
{
|
||||||
|
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
||||||
|
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
||||||
|
fail_unless(sad->get_other_esa_id(sad, 1) == 0,
|
||||||
|
"Got other esa id for nonexistent SAD entry");
|
||||||
|
fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
|
||||||
|
"Error inserting SAD entry");
|
||||||
|
fail_unless(sad->get_other_esa_id(sad, 23) == 0,
|
||||||
|
"Got own esa id");
|
||||||
|
|
||||||
|
sad->destroy(sad);
|
||||||
|
addr->destroy(addr);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
START_TEST(test_get_dst_host)
|
START_TEST(test_get_dst_host)
|
||||||
{
|
{
|
||||||
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
||||||
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
||||||
fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50),
|
fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
|
||||||
"Error inserting SAD entry");
|
"Error inserting SAD entry");
|
||||||
|
|
||||||
host_t *dst = sad->get_dst_host(sad, 54, 42, 50);
|
host_t *dst = sad->get_dst_host(sad, 54, 42, 50);
|
||||||
@@ -108,7 +139,7 @@ START_TEST(test_remove)
|
|||||||
{
|
{
|
||||||
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
host_t *addr = host_create_from_string("127.0.0.1", 1024);
|
||||||
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
|
||||||
fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50),
|
fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
|
||||||
"Error inserting SAD entry");
|
"Error inserting SAD entry");
|
||||||
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
|
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
|
||||||
"Error getting esa id");
|
"Error getting esa id");
|
||||||
@@ -151,6 +182,11 @@ Suite *make_kernel_sad_tests()
|
|||||||
tcase_add_test(tc, test_get_esa_id_nonexistent);
|
tcase_add_test(tc, test_get_esa_id_nonexistent);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
tc = tcase_create("get_other_esa_id");
|
||||||
|
tcase_add_test(tc, test_get_other_esa_id);
|
||||||
|
tcase_add_test(tc, test_get_other_esa_id_nonexistent);
|
||||||
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("get_dst_host");
|
tc = tcase_create("get_dst_host");
|
||||||
tcase_add_test(tc, test_get_dst_host);
|
tcase_add_test(tc, test_get_dst_host);
|
||||||
tcase_add_test(tc, test_get_dst_host_nonexistent);
|
tcase_add_test(tc, test_get_dst_host_nonexistent);
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ START_TEST(test_derive_ike_keys)
|
|||||||
fail_if(!ng, "Unable to create nonce generator");
|
fail_if(!ng, "Unable to create nonce generator");
|
||||||
fail_unless(ng->nonce_gen.allocate_nonce(&ng->nonce_gen, 32, &nonce),
|
fail_unless(ng->nonce_gen.allocate_nonce(&ng->nonce_gen, 32, &nonce),
|
||||||
"Unable to allocate nonce");
|
"Unable to allocate nonce");
|
||||||
ng->nonce_gen.destroy(&ng->nonce_gen);
|
|
||||||
|
|
||||||
tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT);
|
tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT);
|
||||||
fail_if(!dh, "Unable to create DH");
|
fail_if(!dh, "Unable to create DH");
|
||||||
@@ -69,6 +68,7 @@ START_TEST(test_derive_ike_keys)
|
|||||||
fail_if(aead->get_block_size(aead) != 16, "Block size mismatch %d",
|
fail_if(aead->get_block_size(aead) != 16, "Block size mismatch %d",
|
||||||
aead->get_block_size(aead));
|
aead->get_block_size(aead));
|
||||||
|
|
||||||
|
ng->nonce_gen.destroy(&ng->nonce_gen);
|
||||||
proposal->destroy(proposal);
|
proposal->destroy(proposal);
|
||||||
dh->dh.destroy(&dh->dh);
|
dh->dh.destroy(&dh->dh);
|
||||||
ike_sa_id->destroy(ike_sa_id);
|
ike_sa_id->destroy(ike_sa_id);
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ START_TEST(test_nonceg_creation)
|
|||||||
|
|
||||||
ng = tkm_nonceg_create();
|
ng = tkm_nonceg_create();
|
||||||
fail_if(ng == NULL, "Error creating tkm nonce generator");
|
fail_if(ng == NULL, "Error creating tkm nonce generator");
|
||||||
fail_if(ng->get_id(ng) == 0, "Invalid context id (0)");
|
|
||||||
|
|
||||||
ng->nonce_gen.destroy(&ng->nonce_gen);
|
ng->nonce_gen.destroy(&ng->nonce_gen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,8 @@ enum alert_t {
|
|||||||
ALERT_UNIQUE_REPLACE,
|
ALERT_UNIQUE_REPLACE,
|
||||||
/** IKE_SA deleted because of "keep" unique policy, no argument */
|
/** IKE_SA deleted because of "keep" unique policy, no argument */
|
||||||
ALERT_UNIQUE_KEEP,
|
ALERT_UNIQUE_KEEP,
|
||||||
/** IKE_SA kept on failed child SA establishment, no argument */
|
/** IKE_SA kept on failed child SA establishment, argument is an int (!=0 if
|
||||||
|
* first child SA) */
|
||||||
ALERT_KEEP_ON_CHILD_SA_FAILURE,
|
ALERT_KEEP_ON_CHILD_SA_FAILURE,
|
||||||
/** allocating virtual IP failed, linked_list_t of host_t requested */
|
/** allocating virtual IP failed, linked_list_t of host_t requested */
|
||||||
ALERT_VIP_FAILURE,
|
ALERT_VIP_FAILURE,
|
||||||
|
|||||||
@@ -64,6 +64,11 @@ struct private_child_create_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t other_nonce;
|
chunk_t other_nonce;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nonce generator
|
||||||
|
*/
|
||||||
|
nonce_gen_t *nonceg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* config to create the CHILD_SA from
|
* config to create the CHILD_SA from
|
||||||
*/
|
*/
|
||||||
@@ -216,22 +221,12 @@ static status_t get_nonce(message_t *message, chunk_t *nonce)
|
|||||||
*/
|
*/
|
||||||
static status_t generate_nonce(private_child_create_t *this)
|
static status_t generate_nonce(private_child_create_t *this)
|
||||||
{
|
{
|
||||||
nonce_gen_t *nonceg;
|
if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE,
|
||||||
|
&this->my_nonce))
|
||||||
nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
|
|
||||||
if (!nonceg)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "no nonce generator found to create nonce");
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &this->my_nonce))
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "nonce allocation failed");
|
DBG1(DBG_IKE, "nonce allocation failed");
|
||||||
nonceg->destroy(nonceg);
|
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
nonceg->destroy(nonceg);
|
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1092,7 +1087,10 @@ METHOD(task_t, process_r, status_t,
|
|||||||
static void handle_child_sa_failure(private_child_create_t *this,
|
static void handle_child_sa_failure(private_child_create_t *this,
|
||||||
message_t *message)
|
message_t *message)
|
||||||
{
|
{
|
||||||
if (message->get_exchange_type(message) == IKE_AUTH &&
|
bool is_first;
|
||||||
|
|
||||||
|
is_first = message->get_exchange_type(message) == IKE_AUTH;
|
||||||
|
if (is_first &&
|
||||||
lib->settings->get_bool(lib->settings,
|
lib->settings->get_bool(lib->settings,
|
||||||
"%s.close_ike_on_child_failure", FALSE, lib->ns))
|
"%s.close_ike_on_child_failure", FALSE, lib->ns))
|
||||||
{
|
{
|
||||||
@@ -1106,7 +1104,8 @@ static void handle_child_sa_failure(private_child_create_t *this,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
|
DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
|
||||||
charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE);
|
charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE,
|
||||||
|
is_first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1627,6 +1626,7 @@ METHOD(task_t, destroy, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DESTROY_IF(this->config);
|
DESTROY_IF(this->config);
|
||||||
|
DESTROY_IF(this->nonceg);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1666,6 +1666,14 @@ child_create_t *child_create_create(ike_sa_t *ike_sa,
|
|||||||
.retry = FALSE,
|
.retry = FALSE,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this->nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
|
||||||
|
if (!this->nonceg)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "no nonce generator found to create nonce");
|
||||||
|
free(this);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (config)
|
if (config)
|
||||||
{
|
{
|
||||||
this->public.task.build = _build_i;
|
this->public.task.build = _build_i;
|
||||||
|
|||||||
@@ -89,6 +89,11 @@ struct private_ike_init_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t other_nonce;
|
chunk_t other_nonce;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nonce generator
|
||||||
|
*/
|
||||||
|
nonce_gen_t *nonceg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Negotiated proposal used for IKE_SA
|
* Negotiated proposal used for IKE_SA
|
||||||
*/
|
*/
|
||||||
@@ -428,21 +433,12 @@ METHOD(task_t, build_i, status_t,
|
|||||||
/* generate nonce only when we are trying the first time */
|
/* generate nonce only when we are trying the first time */
|
||||||
if (this->my_nonce.ptr == NULL)
|
if (this->my_nonce.ptr == NULL)
|
||||||
{
|
{
|
||||||
nonce_gen_t *nonceg;
|
if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE,
|
||||||
|
&this->my_nonce))
|
||||||
nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
|
|
||||||
if (!nonceg)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "no nonce generator found to create nonce");
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &this->my_nonce))
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "nonce allocation failed");
|
DBG1(DBG_IKE, "nonce allocation failed");
|
||||||
nonceg->destroy(nonceg);
|
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
nonceg->destroy(nonceg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->cookie.ptr)
|
if (this->cookie.ptr)
|
||||||
@@ -477,19 +473,11 @@ METHOD(task_t, process_r, status_t,
|
|||||||
DBG0(DBG_IKE, "%H is initiating an IKE_SA", message->get_source(message));
|
DBG0(DBG_IKE, "%H is initiating an IKE_SA", message->get_source(message));
|
||||||
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
|
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
|
||||||
|
|
||||||
nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
|
if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE, &this->my_nonce))
|
||||||
if (!nonceg)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "no nonce generator found to create nonce");
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &this->my_nonce))
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "nonce allocation failed");
|
DBG1(DBG_IKE, "nonce allocation failed");
|
||||||
nonceg->destroy(nonceg);
|
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
nonceg->destroy(nonceg);
|
|
||||||
|
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
{
|
{
|
||||||
@@ -756,6 +744,7 @@ METHOD(task_t, destroy, void,
|
|||||||
{
|
{
|
||||||
DESTROY_IF(this->dh);
|
DESTROY_IF(this->dh);
|
||||||
DESTROY_IF(this->proposal);
|
DESTROY_IF(this->proposal);
|
||||||
|
DESTROY_IF(this->nonceg);
|
||||||
chunk_free(&this->my_nonce);
|
chunk_free(&this->my_nonce);
|
||||||
chunk_free(&this->other_nonce);
|
chunk_free(&this->other_nonce);
|
||||||
chunk_free(&this->cookie);
|
chunk_free(&this->cookie);
|
||||||
@@ -801,6 +790,14 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa)
|
|||||||
"%s.signature_authentication", TRUE, lib->ns),
|
"%s.signature_authentication", TRUE, lib->ns),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this->nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
|
||||||
|
if (!this->nonceg)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "no nonce generator found to create nonce");
|
||||||
|
free(this);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (initiator)
|
if (initiator)
|
||||||
{
|
{
|
||||||
this->public.task.build = _build_i;
|
this->public.task.build = _build_i;
|
||||||
|
|||||||
Reference in New Issue
Block a user