diff options
author | Martin Willi <martin@revosec.ch> | 2010-10-28 14:40:54 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-10-28 15:08:14 +0200 |
commit | bb162175817aea3ac76c61c07fb1d1407ee02965 (patch) | |
tree | 0ecef3a7774d3a964b87c89b0a3144f1827430b7 | |
parent | d454c586ab5260a83c916782caa43ebad9988575 (diff) | |
download | strongswan-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.c | 25 | ||||
-rw-r--r-- | src/libcharon/config/proposal.h | 10 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/proposal_substructure.c | 4 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/sa_payload.c | 11 | ||||
-rw-r--r-- | src/libcharon/plugins/ha/ha_dispatcher.c | 4 |
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); |