* Add an IKEv1 IKE proposal to the substructure
*/
static void set_from_proposal_v1_ike(private_proposal_substructure_t *this,
- proposal_t *proposal)
+ proposal_t *proposal, int number)
{
transform_substructure_t *transform;
u_int16_t alg, key_size;
enumerator_t *enumerator;
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);
if (enumerator->enumerate(enumerator, &alg, &key_size))
* Add an IKEv1 ESP proposal to the substructure
*/
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;
u_int16_t alg, key_size;
if (enumerator->enumerate(enumerator, &alg, &key_size))
{
transform = transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1,
- 0, alg);
+ number, alg);
if (key_size)
{
transform->add_transform_attribute(transform,
switch (proposal->get_protocol(proposal))
{
case PROTO_IKE:
- set_from_proposal_v1_ike(this, proposal);
+ set_from_proposal_v1_ike(this, proposal, 0);
break;
case PROTO_ESP:
- set_from_proposal_v1_esp(this, proposal);
+ set_from_proposal_v1_esp(this, proposal, 0);
break;
default:
break;
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;
+}
* Creates a proposal_substructure_t from a proposal_t.
*
* @param type PROPOSAL_SUBSTRUCTURE or PROPOSAL_SUBSTRUCTURE_V1
- * @param proposal proposal to build a substruct out of it
- * @return proposal_substructure_t object
+ * @param proposal proposal to build a substruct out of it
+ * @return proposal_substructure_t object
*/
proposal_substructure_t *proposal_substructure_create_from_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_ @}*/
proposal_t *proposal;
this = (private_sa_payload_t*)sa_payload_create(type);
- enumerator = proposals->create_enumerator(proposals);
- while (enumerator->enumerate(enumerator, &proposal))
+ if (type == SECURITY_ASSOCIATION)
{
- add_proposal(this, proposal);
+ enumerator = proposals->create_enumerator(proposals);
+ while (enumerator->enumerate(enumerator, &proposal))
+ {
+ add_proposal(this, proposal);
+ }
+ 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);
}
- enumerator->destroy(enumerator);
-
return &this->public;
}