Encode multiple IKEv1 proposals in a single transform substructure

This commit is contained in:
Martin Willi
2012-03-20 17:30:48 +01:00
parent f9450fc9f7
commit 62a27ba347
3 changed files with 73 additions and 12 deletions
@@ -760,14 +760,14 @@ proposal_substructure_t *proposal_substructure_create(payload_type_t type)
* Add an IKEv1 IKE proposal to the substructure * Add an IKEv1 IKE proposal to the substructure
*/ */
static void set_from_proposal_v1_ike(private_proposal_substructure_t *this, static void set_from_proposal_v1_ike(private_proposal_substructure_t *this,
proposal_t *proposal) proposal_t *proposal, int number)
{ {
transform_substructure_t *transform; transform_substructure_t *transform;
u_int16_t alg, key_size; u_int16_t alg, key_size;
enumerator_t *enumerator; enumerator_t *enumerator;
transform = transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1, transform = transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1,
0, IKEV1_TRANSID_KEY_IKE); number, IKEV1_TRANSID_KEY_IKE);
enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM); enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM);
if (enumerator->enumerate(enumerator, &alg, &key_size)) if (enumerator->enumerate(enumerator, &alg, &key_size))
@@ -829,7 +829,7 @@ static void set_from_proposal_v1_ike(private_proposal_substructure_t *this,
* Add an IKEv1 ESP proposal to the substructure * Add an IKEv1 ESP proposal to the substructure
*/ */
static void set_from_proposal_v1_esp(private_proposal_substructure_t *this, static void set_from_proposal_v1_esp(private_proposal_substructure_t *this,
proposal_t *proposal) proposal_t *proposal, int number)
{ {
transform_substructure_t *transform = NULL; transform_substructure_t *transform = NULL;
u_int16_t alg, key_size; u_int16_t alg, key_size;
@@ -839,7 +839,7 @@ static void set_from_proposal_v1_esp(private_proposal_substructure_t *this,
if (enumerator->enumerate(enumerator, &alg, &key_size)) if (enumerator->enumerate(enumerator, &alg, &key_size))
{ {
transform = transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1, transform = transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1,
0, alg); number, alg);
if (key_size) if (key_size)
{ {
transform->add_transform_attribute(transform, transform->add_transform_attribute(transform,
@@ -968,10 +968,10 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(
switch (proposal->get_protocol(proposal)) switch (proposal->get_protocol(proposal))
{ {
case PROTO_IKE: case PROTO_IKE:
set_from_proposal_v1_ike(this, proposal); set_from_proposal_v1_ike(this, proposal, 0);
break; break;
case PROTO_ESP: case PROTO_ESP:
set_from_proposal_v1_esp(this, proposal); set_from_proposal_v1_esp(this, proposal, 0);
break; break;
default: default:
break; break;
@@ -1003,3 +1003,43 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(
return &this->public; return &this->public;
} }
/**
* See header.
*/
proposal_substructure_t *proposal_substructure_create_from_proposals(
linked_list_t *proposals)
{
private_proposal_substructure_t *this = NULL;
enumerator_t *enumerator;
proposal_t *proposal;
int number = 0;
enumerator = proposals->create_enumerator(proposals);
while (enumerator->enumerate(enumerator, &proposal))
{
if (!this)
{
this = (private_proposal_substructure_t*)
proposal_substructure_create_from_proposal(
PROPOSAL_SUBSTRUCTURE_V1, proposal);
}
else
{
switch (proposal->get_protocol(proposal))
{
case PROTO_IKE:
set_from_proposal_v1_ike(this, proposal, ++number);
break;
case PROTO_ESP:
set_from_proposal_v1_esp(this, proposal, ++number);
break;
default:
break;
}
}
}
enumerator->destroy(enumerator);
return &this->public;
}
@@ -127,10 +127,19 @@ proposal_substructure_t *proposal_substructure_create(payload_type_t type);
* Creates a proposal_substructure_t from a proposal_t. * Creates a proposal_substructure_t from a proposal_t.
* *
* @param type PROPOSAL_SUBSTRUCTURE or PROPOSAL_SUBSTRUCTURE_V1 * @param type PROPOSAL_SUBSTRUCTURE or PROPOSAL_SUBSTRUCTURE_V1
* @param proposal proposal to build a substruct out of it * @param proposal proposal to build a substruct out of it
* @return proposal_substructure_t object * @return proposal_substructure_t object
*/ */
proposal_substructure_t *proposal_substructure_create_from_proposal( proposal_substructure_t *proposal_substructure_create_from_proposal(
payload_type_t type, proposal_t *proposal); payload_type_t type, proposal_t *proposal);
/**
* Creates a proposal_substructure_t from a list of proposal_t (IKEv1 only).
*
* @param proposal proposal to build a substruct out of it
* @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1
*/
proposal_substructure_t *proposal_substructure_create_from_proposals(
linked_list_t *proposals);
#endif /** PROPOSAL_SUBSTRUCTURE_H_ @}*/ #endif /** PROPOSAL_SUBSTRUCTURE_H_ @}*/
+16 -4
View File
@@ -398,13 +398,25 @@ sa_payload_t *sa_payload_create_from_proposal_list(payload_type_t type,
proposal_t *proposal; proposal_t *proposal;
this = (private_sa_payload_t*)sa_payload_create(type); this = (private_sa_payload_t*)sa_payload_create(type);
enumerator = proposals->create_enumerator(proposals); if (type == SECURITY_ASSOCIATION)
while (enumerator->enumerate(enumerator, &proposal))
{ {
add_proposal(this, proposal); enumerator = proposals->create_enumerator(proposals);
while (enumerator->enumerate(enumerator, &proposal))
{
add_proposal(this, proposal);
}
enumerator->destroy(enumerator);
} }
enumerator->destroy(enumerator); else
{ /* IKEv1 encodes multiple proposals in a single substructure
* TODO-IKEv1: Encode ESP+AH proposals in two different substructs */
proposal_substructure_t *substruct;
substruct = proposal_substructure_create_from_proposals(proposals);
substruct->set_is_last_proposal(substruct, TRUE);
this->proposals->insert_last(this->proposals, substruct);
compute_length(this);
}
return &this->public; return &this->public;
} }