mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
child-create: Add support for multiple key exchanges
It also changes that payloads are built before installing the CHILD_SA on the responder, that is, the KE payload is generated before keys are derived, so that key_exchange_t::get_public_key() is called before get_shared_secret(), or it's internal equivalent, which could be relevant for KE implementations that want to ensure that the key can't be used again after the key derivation.
This commit is contained in:
parent
d3da7b1fdd
commit
abce9feb6a
@ -107,29 +107,27 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||
}
|
||||
esa = *(esa_info_t *)(data->enc_key.ptr);
|
||||
|
||||
/* only handle the case where we have both distinct ESP spi's available */
|
||||
if (esa.spi_r == id->spi)
|
||||
/* only handle the case where we have both distinct ESP SPI's available,
|
||||
* which is always the outbound SA */
|
||||
if (esa.spi_l == id->spi)
|
||||
{
|
||||
chunk_free(&esa.nonce_i);
|
||||
chunk_free(&esa.nonce_r);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
spi_loc = esa.spi_l;
|
||||
spi_rem = id->spi;
|
||||
local = id->src;
|
||||
peer = id->dst;
|
||||
|
||||
if (data->initiator)
|
||||
{
|
||||
spi_loc = id->spi;
|
||||
spi_rem = esa.spi_r;
|
||||
local = id->dst;
|
||||
peer = id->src;
|
||||
nonce_loc = &esa.nonce_i;
|
||||
nonce_rem = &esa.nonce_r;
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_loc = esa.spi_r;
|
||||
spi_rem = id->spi;
|
||||
local = id->src;
|
||||
peer = id->dst;
|
||||
nonce_loc = &esa.nonce_r;
|
||||
nonce_rem = &esa.nonce_i;
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
|
||||
|
||||
INIT(esa_info_i,
|
||||
.isa_id = this->isa_ctx_id,
|
||||
.spi_r = proposal->get_spi(proposal),
|
||||
.spi_l = proposal->get_spi(proposal),
|
||||
.nonce_i = chunk_clone(nonce_i),
|
||||
.nonce_r = chunk_clone(nonce_r),
|
||||
.is_encr_r = FALSE,
|
||||
@ -230,15 +230,15 @@ METHOD(keymat_v2_t, derive_child_keys, bool,
|
||||
|
||||
INIT(esa_info_r,
|
||||
.isa_id = this->isa_ctx_id,
|
||||
.spi_r = proposal->get_spi(proposal),
|
||||
.spi_l = proposal->get_spi(proposal),
|
||||
.nonce_i = chunk_clone(nonce_i),
|
||||
.nonce_r = chunk_clone(nonce_r),
|
||||
.is_encr_r = TRUE,
|
||||
.dh_id = dh_id,
|
||||
);
|
||||
|
||||
DBG1(DBG_CHD, "passing on esa info (isa: %llu, spi_r: %x, dh_id: %llu)",
|
||||
esa_info_i->isa_id, ntohl(esa_info_i->spi_r), esa_info_i->dh_id);
|
||||
DBG1(DBG_CHD, "passing on esa info (isa: %llu, spi_l: %x, dh_id: %llu)",
|
||||
esa_info_i->isa_id, ntohl(esa_info_i->spi_l), esa_info_i->dh_id);
|
||||
|
||||
/* store ESA info in encr_i/r, which is passed to add_sa */
|
||||
*encr_i = chunk_create((u_char *)esa_info_i, sizeof(esa_info_t));
|
||||
@ -296,6 +296,12 @@ METHOD(keymat_v2_t, get_skd, pseudo_random_function_t,
|
||||
{
|
||||
isa_info_t *isa_info;
|
||||
|
||||
if (!this->ae_ctx_id)
|
||||
{
|
||||
*skd = chunk_empty;
|
||||
return PRF_UNDEFINED;
|
||||
}
|
||||
|
||||
INIT(isa_info,
|
||||
.parent_isa_id = this->isa_ctx_id,
|
||||
.ae_id = this->ae_ctx_id,
|
||||
|
@ -49,9 +49,9 @@ struct esa_info_t {
|
||||
isa_id_type isa_id;
|
||||
|
||||
/**
|
||||
* Responder SPI of child SA.
|
||||
* Local SPI of child SA.
|
||||
*/
|
||||
esp_spi_type spi_r;
|
||||
esp_spi_type spi_l;
|
||||
|
||||
/**
|
||||
* Initiator nonce.
|
||||
|
@ -107,7 +107,7 @@ START_TEST(test_derive_child_keys)
|
||||
fail_if(!info, "encr_i does not contain esa information");
|
||||
fail_if(info->isa_id != keymat->get_isa_id(keymat),
|
||||
"Isa context id mismatch (encr_i)");
|
||||
fail_if(info->spi_r != 42,
|
||||
fail_if(info->spi_l != 42,
|
||||
"SPI mismatch (encr_i)");
|
||||
fail_unless(chunk_equals(info->nonce_i, nonce),
|
||||
"nonce_i mismatch (encr_i)");
|
||||
@ -124,7 +124,7 @@ START_TEST(test_derive_child_keys)
|
||||
fail_if(!info, "encr_r does not contain esa information");
|
||||
fail_if(info->isa_id != keymat->get_isa_id(keymat),
|
||||
"Isa context id mismatch (encr_r)");
|
||||
fail_if(info->spi_r != 42,
|
||||
fail_if(info->spi_l != 42,
|
||||
"SPI mismatch (encr_r)");
|
||||
fail_unless(chunk_equals(info->nonce_i, nonce),
|
||||
"nonce_i mismatch (encr_r)");
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user