bool no_dh, bool ike_auth)
{
status_t status, status_i, status_o;
+ child_sa_outbound_state_t out_state;
chunk_t nonce_i, nonce_r;
chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
status_i = this->child_sa->install(this->child_sa, encr_r, integ_r,
this->my_spi, this->my_cpi, this->initiator,
TRUE, this->tfcv3);
- status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
- this->other_spi, this->other_cpi, this->initiator,
- FALSE, this->tfcv3);
}
- else if (!this->rekey)
+ else
{
status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
this->my_spi, this->my_cpi, this->initiator,
TRUE, this->tfcv3);
- status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
+ }
+ if (this->rekey)
+ { /* during rekeyings we install the outbound SA and/or policies
+ * separately: as responder when we receive the delete for the old
+ * SA, as initiator pretty much immediately in the ike-rekey task,
+ * unless there was a rekey collision that we lost */
+ if (this->initiator)
+ {
+ status_o = this->child_sa->register_outbound(this->child_sa,
+ encr_i, integ_i, this->other_spi, this->other_cpi,
+ this->tfcv3);
+ }
+ else
+ {
+ status_o = this->child_sa->register_outbound(this->child_sa,
+ encr_r, integ_r, this->other_spi, this->other_cpi,
+ this->tfcv3);
+ }
+ }
+ else if (this->initiator)
+ {
+ status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
this->other_spi, this->other_cpi, this->initiator,
FALSE, this->tfcv3);
}
else
- { /* as responder during a rekeying we only install the inbound
- * SA now, the outbound SA and policies are installed when we
- * receive the delete for the old SA */
- status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
- this->my_spi, this->my_cpi, this->initiator,
- TRUE, this->tfcv3);
- status_o = this->child_sa->register_outbound(this->child_sa, encr_r,
- integ_r, this->other_spi, this->other_cpi,
- this->tfcv3);
+ {
+ status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
+ this->other_spi, this->other_cpi, this->initiator,
+ FALSE, this->tfcv3);
}
}
this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
other_ts = linked_list_create_from_enumerator(
this->child_sa->create_ts_enumerator(this->child_sa, FALSE));
+ out_state = this->child_sa->get_outbound_state(this->child_sa);
DBG0(DBG_IKE, "%sCHILD_SA %s{%d} established "
"with SPIs %.8x_i %.8x_o and TS %#R === %#R",
- this->rekey && !this->initiator ? "inbound " : "",
+ (out_state == CHILD_OUTBOUND_INSTALLED) ? "" : "inbound ",
this->child_sa->get_name(this->child_sa),
this->child_sa->get_unique_id(this->child_sa),
ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
CHILD_OUTBOUND_REGISTERED);
assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
CHILD_OUTBOUND_INSTALLED);
+ assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+ CHILD_OUTBOUND_INSTALLED);
+ assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
}
else
{
CHILD_OUTBOUND_INSTALLED);
assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
CHILD_OUTBOUND_REGISTERED);
+ assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+ CHILD_OUTBOUND_REGISTERED);
+ assert_ipsec_sas_installed(a, 1, 2, 3, 6);
}
- assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
- assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
/* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
if (data[_i].spi_del_b == 2)
{
CHILD_OUTBOUND_REGISTERED);
assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
CHILD_OUTBOUND_INSTALLED);
+ assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+ CHILD_OUTBOUND_INSTALLED);
+ assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
}
else
{
CHILD_OUTBOUND_INSTALLED);
assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
CHILD_OUTBOUND_REGISTERED);
+ assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+ CHILD_OUTBOUND_REGISTERED);
+ assert_ipsec_sas_installed(b, 1, 2, 4, 5);
}
- assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
- assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
/* we don't expect this hook to get called anymore */
assert_hook_not_called(child_rekey);
assert_jobs_scheduled(1);
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
+ data[_i].spi_del_b == 2 ? CHILD_OUTBOUND_INSTALLED
+ : CHILD_OUTBOUND_REGISTERED);
assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING,
CHILD_OUTBOUND_NONE);
assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
CHILD_OUTBOUND_INSTALLED);
assert_child_sa_count(b, 3);
- assert_ipsec_sas_installed(b, 2, 4, 5, 6,
- data[_i].spi_del_b == 2 ? 1 : 3);
+ if (data[_i].spi_del_b == 2)
+ {
+ assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
+ }
+ else
+ {
+ assert_ipsec_sas_installed(b, 2, 3, 4, 5);
+ }
assert_scheduler();
/* <-- INFORMATIONAL { D } */
assert_jobs_scheduled(1);
exchange_test_helper->process_message(exchange_test_helper, a, NULL);
assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
+ data[_i].spi_del_a == 1 ? CHILD_OUTBOUND_INSTALLED
+ : CHILD_OUTBOUND_REGISTERED);
assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
CHILD_OUTBOUND_NONE);
assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
CHILD_OUTBOUND_INSTALLED);
assert_child_sa_count(a, 3);
- assert_ipsec_sas_installed(a, 1, 3, 5, 6,
- data[_i].spi_del_a == 1 ? 2 : 4);
+ if (data[_i].spi_del_a == 1)
+ {
+ assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
+ }
+ else
+ {
+ assert_ipsec_sas_installed(a, 1, 3, 4, 6);
+ }
assert_scheduler();
/* <-- INFORMATIONAL { D } */
assert_jobs_scheduled(1);
CHILD_OUTBOUND_REGISTERED);
assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
CHILD_OUTBOUND_INSTALLED);
+ assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+ CHILD_OUTBOUND_INSTALLED);
+ assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
}
else
{
CHILD_OUTBOUND_INSTALLED);
assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
CHILD_OUTBOUND_REGISTERED);
+ assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+ CHILD_OUTBOUND_REGISTERED);
+ assert_ipsec_sas_installed(b, 1, 2, 4, 5);
}
- assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
- assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6);
/* <-- INFORMATIONAL { D } */
assert_hook_not_called(child_rekey);
assert_hook_rekey(child_rekey, 1, data[_i].spi_a);
exchange_test_helper->process_message(exchange_test_helper, a, msg);
assert_hook();
+ assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+ CHILD_OUTBOUND_INSTALLED);
+ assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6);
}
else
{
assert_hook_not_called(child_rekey);
exchange_test_helper->process_message(exchange_test_helper, a, msg);
assert_hook();
+ assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+ CHILD_OUTBOUND_REGISTERED);
+ assert_ipsec_sas_installed(a, 1, 3, 4, 6);
}
- assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
CHILD_OUTBOUND_NONE);
assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
CHILD_OUTBOUND_INSTALLED);
- assert_ipsec_sas_installed(a, 1, 3, 5, 6,
- data[_i].spi_del_a == 1 ? 2 : 4);
assert_child_sa_count(a, 3);
/* we don't expect this hook to get called anymore */
CHILD_OUTBOUND_REGISTERED);
assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
CHILD_OUTBOUND_INSTALLED);
+ assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+ CHILD_OUTBOUND_INSTALLED);
}
else
{
CHILD_OUTBOUND_INSTALLED);
assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,
CHILD_OUTBOUND_REGISTERED);
+ assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
+ CHILD_OUTBOUND_REGISTERED);
}
- assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
/* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */
if (data[_i].spi_del_b == 2)
{
CHILD_OUTBOUND_REGISTERED);
assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
CHILD_OUTBOUND_INSTALLED);
+ assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+ CHILD_OUTBOUND_INSTALLED);
}
else
{
CHILD_OUTBOUND_INSTALLED);
assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
CHILD_OUTBOUND_REGISTERED);
+ assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
+ CHILD_OUTBOUND_REGISTERED);
}
- assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
+
/* we don't expect this hook to get called anymore */
assert_hook_not_called(child_rekey);
assert_jobs_scheduled(1);
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
+ data[_i].spi_del_b == 2 ? CHILD_OUTBOUND_INSTALLED
+ : CHILD_OUTBOUND_REGISTERED);
assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING,
CHILD_OUTBOUND_NONE);
assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED,
assert_jobs_scheduled(1);
exchange_test_helper->process_message(exchange_test_helper, a, NULL);
assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING,
- CHILD_OUTBOUND_INSTALLED);
+ data[_i].spi_del_a == 1 ? CHILD_OUTBOUND_INSTALLED
+ : CHILD_OUTBOUND_REGISTERED);
assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING,
CHILD_OUTBOUND_NONE);
assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED,