Store proposal number in proposal_t to reuse it in the selected proposal

According to RFC 5996 3.3.1, we MUST reuse the proposal number of
the selected proposal in the SA payload reply.
This commit is contained in:
Martin Willi
2010-10-28 15:08:14 +02:00
parent d454c586ab
commit bb16217581
5 changed files with 42 additions and 12 deletions
+20 -5
View File
@@ -87,6 +87,11 @@ struct private_proposal_t {
* senders SPI
*/
u_int64_t spi;
/**
* Proposal number
*/
u_int number;
};
/**
@@ -311,7 +316,7 @@ METHOD(proposal_t, select_proposal, proposal_t*,
return NULL;
}
selected = proposal_create(this->protocol);
selected = proposal_create(this->protocol, other->number);
/* select encryption algorithm */
if (select_algo(this->encryption_algos, other->encryption_algos, private,
@@ -473,6 +478,12 @@ static bool algo_list_equals(linked_list_t *l1, linked_list_t *l2)
return equals;
}
METHOD(proposal_t, get_number, u_int,
private_proposal_t *this)
{
return this->number;
}
METHOD(proposal_t, equals, bool,
private_proposal_t *this, proposal_t *other_pub)
{
@@ -493,8 +504,9 @@ METHOD(proposal_t, equals, bool,
METHOD(proposal_t, clone_, proposal_t*,
private_proposal_t *this)
{
private_proposal_t *clone = (private_proposal_t*)proposal_create(this->protocol);
private_proposal_t *clone;
clone = (private_proposal_t*)proposal_create(this->protocol, 0);
clone_algo_list(this->encryption_algos, clone->encryption_algos);
clone_algo_list(this->integrity_algos, clone->integrity_algos);
clone_algo_list(this->prf_algos, clone->prf_algos);
@@ -502,6 +514,7 @@ METHOD(proposal_t, clone_, proposal_t*,
clone_algo_list(this->esns, clone->esns);
clone->spi = this->spi;
clone->number = this->number;
return &clone->public;
}
@@ -685,7 +698,7 @@ METHOD(proposal_t, destroy, void,
/*
* Describtion in header-file
*/
proposal_t *proposal_create(protocol_id_t protocol)
proposal_t *proposal_create(protocol_id_t protocol, u_int number)
{
private_proposal_t *this;
@@ -700,11 +713,13 @@ proposal_t *proposal_create(protocol_id_t protocol)
.get_protocol = _get_protocol,
.set_spi = _set_spi,
.get_spi = _get_spi,
.get_number = _get_number,
.equals = _equals,
.clone = _clone_,
.destroy = _destroy,
},
.protocol = protocol,
.number = number,
.encryption_algos = linked_list_create(),
.integrity_algos = linked_list_create(),
.prf_algos = linked_list_create(),
@@ -837,7 +852,7 @@ static void proposal_add_supported_ike(private_proposal_t *this)
*/
proposal_t *proposal_create_default(protocol_id_t protocol)
{
private_proposal_t *this = (private_proposal_t*)proposal_create(protocol);
private_proposal_t *this = (private_proposal_t*)proposal_create(protocol, 0);
switch (protocol)
{
@@ -872,7 +887,7 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
*/
proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs)
{
private_proposal_t *this = (private_proposal_t*)proposal_create(protocol);
private_proposal_t *this = (private_proposal_t*)proposal_create(protocol, 0);
chunk_t string = {(void*)algs, strlen(algs)};
chunk_t alg;
status_t status = SUCCESS;
+9 -1
View File
@@ -160,6 +160,13 @@ struct proposal_t {
*/
void (*set_spi) (proposal_t *this, u_int64_t spi);
/**
* Get the proposal number, as encoded in SA payload
*
* @return proposal number
*/
u_int (*get_number)(proposal_t *this);
/**
* Check for the eqality of two proposals.
*
@@ -185,9 +192,10 @@ struct proposal_t {
* Create a child proposal for AH, ESP or IKE.
*
* @param protocol protocol, such as PROTO_ESP
* @param number proposal number, as encoded in SA payload
* @return proposal_t object
*/
proposal_t *proposal_create(protocol_id_t protocol);
proposal_t *proposal_create(protocol_id_t protocol, u_int number);
/**
* Create a default proposal if nothing further specified.
@@ -309,7 +309,7 @@ METHOD(proposal_substructure_t, get_proposal, proposal_t*,
proposal_t *proposal;
u_int64_t spi;
proposal = proposal_create(this->protocol_id);
proposal = proposal_create(this->protocol_id, this->proposal_number);
enumerator = this->transforms->create_enumerator(this->transforms);
while (enumerator->enumerate(enumerator, &transform))
@@ -498,7 +498,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(
default:
break;
}
this->proposal_number = 0;
this->proposal_number = proposal->get_number(proposal);
this->protocol_id = proposal->get_protocol(proposal);
return &this->public;
+9 -2
View File
@@ -204,8 +204,15 @@ METHOD(sa_payload_t, add_proposal, void,
last->set_is_last_proposal(last, FALSE);
}
substruct->set_is_last_proposal(substruct, TRUE);
substruct->set_proposal_number(substruct, count + 1);
this->proposals->insert_last(this->proposals, proposal);
if (proposal->get_number(proposal))
{ /* use the selected proposals number, if any */
substruct->set_proposal_number(substruct, proposal->get_number(proposal));
}
else
{
substruct->set_proposal_number(substruct, count + 1);
}
this->proposals->insert_last(this->proposals, substruct);
compute_length(this);
}
+2 -2
View File
@@ -136,7 +136,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
diffie_hellman_t dh = { .get_shared_secret = get_shared_secret,
.destroy = (void*)&secret };
proposal = proposal_create(PROTO_IKE);
proposal = proposal_create(PROTO_IKE, 0);
keymat = ike_sa->get_keymat(ike_sa);
if (integ)
{
@@ -549,7 +549,7 @@ static void process_child_add(private_ha_dispatcher_t *this,
child_sa->set_protocol(child_sa, PROTO_ESP);
child_sa->set_ipcomp(child_sa, ipcomp);
proposal = proposal_create(PROTO_ESP);
proposal = proposal_create(PROTO_ESP, 0);
if (integ)
{
proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM, integ, 0);