aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-10-28 14:40:54 +0200
committerMartin Willi <martin@revosec.ch>2010-10-28 15:08:14 +0200
commitbb162175817aea3ac76c61c07fb1d1407ee02965 (patch)
tree0ecef3a7774d3a964b87c89b0a3144f1827430b7
parentd454c586ab5260a83c916782caa43ebad9988575 (diff)
downloadstrongswan-bb162175817aea3ac76c61c07fb1d1407ee02965.tar.bz2
strongswan-bb162175817aea3ac76c61c07fb1d1407ee02965.tar.xz
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.
-rw-r--r--src/libcharon/config/proposal.c25
-rw-r--r--src/libcharon/config/proposal.h10
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.c4
-rw-r--r--src/libcharon/encoding/payloads/sa_payload.c11
-rw-r--r--src/libcharon/plugins/ha/ha_dispatcher.c4
5 files changed, 42 insertions, 12 deletions
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index 6a29b4164..5b8294599 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -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;
diff --git a/src/libcharon/config/proposal.h b/src/libcharon/config/proposal.h
index 30f63b80d..97af5b60b 100644
--- a/src/libcharon/config/proposal.h
+++ b/src/libcharon/config/proposal.h
@@ -161,6 +161,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.
*
* @param other other proposal to check for equality
@@ -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.
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index a683d72ca..985b03255 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -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;
diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c
index 5689c8094..4fbd4cac0 100644
--- a/src/libcharon/encoding/payloads/sa_payload.c
+++ b/src/libcharon/encoding/payloads/sa_payload.c
@@ -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);
}
diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c
index 4f9496f90..b46a221bd 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -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);