aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.c163
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.h41
-rw-r--r--src/libcharon/encoding/payloads/sa_payload.c69
-rw-r--r--src/libcharon/encoding/payloads/transform_attribute.c19
-rw-r--r--src/libcharon/encoding/payloads/transform_attribute.h4
5 files changed, 173 insertions, 123 deletions
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index 924f5cb48..11d684f5e 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -573,6 +573,41 @@ static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
}
/**
+ * Get IKEv1 authentication attribute from auth_method_t
+ */
+static u_int16_t get_ikev1_auth(auth_method_t method)
+{
+ switch (method)
+ {
+ case AUTH_RSA:
+ return IKEV1_AUTH_RSA_SIG;
+ case AUTH_DSS:
+ return IKEV1_AUTH_DSS_SIG;
+ default:
+ /* TODO-IKEv1: Handle XAUTH methods */
+ /* TODO-IKEv1: Handle ECDSA methods */
+ case AUTH_PSK:
+ return IKEV1_AUTH_PSK;
+ }
+}
+
+/**
+ * Get IKEv1 encapsulation mode
+ */
+static u_int16_t get_ikev1_mode(ipsec_mode_t mode, bool udp)
+{
+ switch (mode)
+ {
+ case MODE_TUNNEL:
+ return udp ? IKEV1_ENCAP_UDP_TUNNEL : IKEV1_ENCAP_TUNNEL;
+ case MODE_TRANSPORT:
+ return udp ? IKEV1_ENCAP_UDP_TRANSPORT : IKEV1_ENCAP_TRANSPORT;
+ default:
+ return IKEV1_ENCAP_TUNNEL;
+ }
+}
+
+/**
* Add an IKE transform to a proposal for IKEv1
*/
static void add_to_proposal_v1_ike(proposal_t *proposal,
@@ -771,7 +806,8 @@ proposal_substructure_t *proposal_substructure_create(payload_type_t type)
* Add an IKEv1 IKE proposal to the substructure
*/
static void set_from_proposal_v1_ike(private_proposal_substructure_t *this,
- proposal_t *proposal, int number)
+ proposal_t *proposal, u_int32_t lifetime,
+ auth_method_t method, int number)
{
transform_substructure_t *transform;
u_int16_t alg, key_size;
@@ -822,23 +858,15 @@ static void set_from_proposal_v1_ike(private_proposal_substructure_t *this,
}
enumerator->destroy(enumerator);
- /* TODO-IKEv1: Add lifetime, non-fixed auth-method and other attributes */
- if(1) /* TODO-IKEv1: Change to 0 if XAUTH is desired. */
- {
transform->add_transform_attribute(transform,
transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
- TATTR_PH1_AUTH_METHOD, IKEV1_AUTH_PSK));
- }else{
- transform->add_transform_attribute(transform,
- transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
- TATTR_PH1_AUTH_METHOD, IKEV1_AUTH_XAUTH_INIT_PSK));
- }
+ TATTR_PH1_AUTH_METHOD, get_ikev1_auth(method)));
transform->add_transform_attribute(transform,
transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
TATTR_PH1_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS));
transform->add_transform_attribute(transform,
transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
- TATTR_PH1_LIFE_DURATION, 10800));
+ TATTR_PH1_LIFE_DURATION, lifetime));
add_transform_substructure(this, transform);
}
@@ -847,7 +875,8 @@ static void set_from_proposal_v1_ike(private_proposal_substructure_t *this,
* Add an IKEv1 ESP proposal to the substructure
*/
static void set_from_proposal_v1_esp(private_proposal_substructure_t *this,
- proposal_t *proposal, int number)
+ proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes,
+ ipsec_mode_t mode, bool udp, int number)
{
transform_substructure_t *transform = NULL;
u_int16_t alg, key_size;
@@ -884,16 +913,27 @@ static void set_from_proposal_v1_esp(private_proposal_substructure_t *this,
}
enumerator->destroy(enumerator);
- /* TODO-IKEv1: Add lifetime and other attributes, ESN */
- transform->add_transform_attribute(transform,
- transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
- TATTR_PH2_ENCAP_MODE, IKEV1_ENCAP_TUNNEL));
transform->add_transform_attribute(transform,
transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
+ TATTR_PH2_ENCAP_MODE, get_ikev1_mode(mode, udp)));
+ if (lifetime)
+ {
+ transform->add_transform_attribute(transform,
+ transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS));
- transform->add_transform_attribute(transform,
- transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
- TATTR_PH2_SA_LIFE_DURATION, 3600));
+ transform->add_transform_attribute(transform,
+ transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
+ TATTR_PH2_SA_LIFE_DURATION, lifetime));
+ }
+ else if (lifebytes)
+ {
+ transform->add_transform_attribute(transform,
+ transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
+ TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_KILOBYTES));
+ transform->add_transform_attribute(transform,
+ transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1,
+ TATTR_PH2_SA_LIFE_DURATION, lifebytes / 1000));
+ }
add_transform_substructure(this, transform);
}
@@ -965,36 +1005,14 @@ static void set_from_proposal_v2(private_proposal_substructure_t *this,
enumerator->destroy(enumerator);
}
-/*
- * Described in header.
+/**
+ * Set SPI and other data from proposal, compute length
*/
-proposal_substructure_t *proposal_substructure_create_from_proposal(
- payload_type_t type, proposal_t *proposal)
+static void set_data(private_proposal_substructure_t *this, proposal_t *proposal)
{
- private_proposal_substructure_t *this;
u_int64_t spi64;
u_int32_t spi32;
- this = (private_proposal_substructure_t*)proposal_substructure_create(type);
-
- if (type == PROPOSAL_SUBSTRUCTURE)
- {
- set_from_proposal_v2(this, proposal);
- }
- else
- {
- switch (proposal->get_protocol(proposal))
- {
- case PROTO_IKE:
- set_from_proposal_v1_ike(this, proposal, 0);
- break;
- case PROTO_ESP:
- set_from_proposal_v1_esp(this, proposal, 0);
- break;
- default:
- break;
- }
- }
/* add SPI, if necessary */
switch (proposal->get_protocol(proposal))
{
@@ -1018,6 +1036,48 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(
this->proposal_number = proposal->get_number(proposal);
this->protocol_id = proposal->get_protocol(proposal);
compute_length(this);
+}
+
+/*
+ * Described in header.
+ */
+proposal_substructure_t *proposal_substructure_create_from_proposal_v2(
+ proposal_t *proposal)
+{
+ private_proposal_substructure_t *this;
+
+ this = (private_proposal_substructure_t*)
+ proposal_substructure_create(SECURITY_ASSOCIATION);
+ set_from_proposal_v2(this, proposal);
+ set_data(this, proposal);
+
+ return &this->public;
+}
+
+/**
+ * See header.
+ */
+proposal_substructure_t *proposal_substructure_create_from_proposal_v1(
+ proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes,
+ auth_method_t auth, ipsec_mode_t mode, bool udp)
+{
+ private_proposal_substructure_t *this;
+
+ this = (private_proposal_substructure_t*)
+ proposal_substructure_create(PROPOSAL_SUBSTRUCTURE_V1);
+ switch (proposal->get_protocol(proposal))
+ {
+ case PROTO_IKE:
+ set_from_proposal_v1_ike(this, proposal, lifetime, auth, 0);
+ break;
+ case PROTO_ESP:
+ set_from_proposal_v1_esp(this, proposal, lifetime,
+ lifebytes, mode, udp, 0);
+ break;
+ default:
+ break;
+ }
+ set_data(this, proposal);
return &this->public;
}
@@ -1025,8 +1085,9 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(
/**
* See header.
*/
-proposal_substructure_t *proposal_substructure_create_from_proposals(
- linked_list_t *proposals)
+proposal_substructure_t *proposal_substructure_create_from_proposals_v1(
+ linked_list_t *proposals, u_int32_t lifetime, u_int64_t lifebytes,
+ auth_method_t auth, ipsec_mode_t mode, bool udp)
{
private_proposal_substructure_t *this = NULL;
enumerator_t *enumerator;
@@ -1039,18 +1100,20 @@ proposal_substructure_t *proposal_substructure_create_from_proposals(
if (!this)
{
this = (private_proposal_substructure_t*)
- proposal_substructure_create_from_proposal(
- PROPOSAL_SUBSTRUCTURE_V1, proposal);
+ proposal_substructure_create_from_proposal_v1(
+ proposal, lifetime, lifebytes, auth, mode, udp);
}
else
{
switch (proposal->get_protocol(proposal))
{
case PROTO_IKE:
- set_from_proposal_v1_ike(this, proposal, ++number);
+ set_from_proposal_v1_ike(this, proposal, lifetime,
+ auth, ++number);
break;
case PROTO_ESP:
- set_from_proposal_v1_esp(this, proposal, ++number);
+ set_from_proposal_v1_esp(this, proposal, lifetime,
+ lifebytes, mode, udp, ++number);
break;
default:
break;
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.h b/src/libcharon/encoding/payloads/proposal_substructure.h
index 496a352ca..de06f916f 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.h
+++ b/src/libcharon/encoding/payloads/proposal_substructure.h
@@ -29,6 +29,8 @@ typedef struct proposal_substructure_t proposal_substructure_t;
#include <encoding/payloads/transform_substructure.h>
#include <config/proposal.h>
#include <utils/linked_list.h>
+#include <kernel/kernel_ipsec.h>
+#include <sa/authenticators/authenticator.h>
/**
* Class representing an IKEv1/IKEv2 proposal substructure.
@@ -124,22 +126,43 @@ struct proposal_substructure_t {
proposal_substructure_t *proposal_substructure_create(payload_type_t type);
/**
- * Creates a proposal_substructure_t from a proposal_t.
+ * Creates an IKEv2 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
+ * @return proposal_substructure_t PROPOSAL_SUBSTRUCTURE
*/
-proposal_substructure_t *proposal_substructure_create_from_proposal(
- payload_type_t type, proposal_t *proposal);
-
+proposal_substructure_t *proposal_substructure_create_from_proposal_v2(
+ proposal_t *proposal);
/**
- * Creates a proposal_substructure_t from a list of proposal_t (IKEv1 only).
+ * Creates an IKEv1 proposal_substructure_t from a proposal_t.
*
* @param proposal proposal to build a substruct out of it
+ * @param lifetime lifetime in seconds
+ * @param lifebytes lifebytes, in bytes
+ * @param auth authentication method to use, or AUTH_NONE
+ * @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL
+ * @param udp TRUE to use UDP encapsulation
+ *
+ *
+ * @return proposal_substructure_t object PROPOSAL_SUBSTRUCTURE_V1
+ */
+proposal_substructure_t *proposal_substructure_create_from_proposal_v1(
+ proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes,
+ auth_method_t auth, ipsec_mode_t mode, bool udp);
+
+/**
+ * Creates an IKEv1 proposal_substructure_t from a list of proposal_t.
+ *
+ * @param proposals list of proposal_t to encode in a substructure
+ * @param lifetime lifetime in seconds
+ * @param lifebytes lifebytes, in bytes
+ * @param auth authentication method to use, or AUTH_NONE
+ * @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL
+ * @param udp TRUE to use UDP encapsulation
* @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1
*/
-proposal_substructure_t *proposal_substructure_create_from_proposals(
- linked_list_t *proposals);
+proposal_substructure_t *proposal_substructure_create_from_proposals_v1(
+ linked_list_t *proposals, u_int32_t lifetime, u_int64_t lifebytes,
+ auth_method_t auth, ipsec_mode_t mode, bool udp);
#endif /** PROPOSAL_SUBSTRUCTURE_H_ @}*/
diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c
index 385517bdd..5f739c94a 100644
--- a/src/libcharon/encoding/payloads/sa_payload.c
+++ b/src/libcharon/encoding/payloads/sa_payload.c
@@ -259,17 +259,12 @@ METHOD(payload_t, get_length, size_t,
/**
* Create a transform substructure from a proposal, add to payload
*/
-static void add_proposal(private_sa_payload_t *this, proposal_t *proposal)
+static void add_proposal_v2(private_sa_payload_t *this, proposal_t *proposal)
{
proposal_substructure_t *substruct, *last;
- payload_type_t subtype = PROPOSAL_SUBSTRUCTURE;
u_int count;
- if (this->type == SECURITY_ASSOCIATION_V1)
- {
- subtype = PROPOSAL_SUBSTRUCTURE_V1;
- }
- substruct = proposal_substructure_create_from_proposal(subtype, proposal);
+ substruct = proposal_substructure_create_from_proposal_v2(proposal);
count = this->proposals->get_count(this->proposals);
if (count > 0)
{
@@ -417,53 +412,6 @@ sa_payload_t *sa_payload_create(payload_type_t type)
/*
* Described in header.
*/
-sa_payload_t *sa_payload_create_from_proposal_list(payload_type_t type,
- linked_list_t *proposals)
-{
- private_sa_payload_t *this;
- enumerator_t *enumerator;
- proposal_t *proposal;
-
- this = (private_sa_payload_t*)sa_payload_create(type);
- if (type == SECURITY_ASSOCIATION)
- {
- 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);
- }
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-sa_payload_t *sa_payload_create_from_proposal(payload_type_t type,
- proposal_t *proposal)
-{
- private_sa_payload_t *this;
-
- this = (private_sa_payload_t*)sa_payload_create(type);
- add_proposal(this, proposal);
-
- return &this->public;
-}
-
-/*
- * Described in header.
- */
sa_payload_t *sa_payload_create_from_proposals_v2(linked_list_t *proposals)
{
private_sa_payload_t *this;
@@ -474,7 +422,7 @@ sa_payload_t *sa_payload_create_from_proposals_v2(linked_list_t *proposals)
enumerator = proposals->create_enumerator(proposals);
while (enumerator->enumerate(enumerator, &proposal))
{
- add_proposal(this, proposal);
+ add_proposal_v2(this, proposal);
}
enumerator->destroy(enumerator);
@@ -489,7 +437,7 @@ sa_payload_t *sa_payload_create_from_proposal_v2(proposal_t *proposal)
private_sa_payload_t *this;
this = (private_sa_payload_t*)sa_payload_create(SECURITY_ASSOCIATION);
- add_proposal(this, proposal);
+ add_proposal_v2(this, proposal);
return &this->public;
@@ -505,11 +453,12 @@ sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
proposal_substructure_t *substruct;
private_sa_payload_t *this;
- this = (private_sa_payload_t*)sa_payload_create(SECURITY_ASSOCIATION);
+ this = (private_sa_payload_t*)sa_payload_create(SECURITY_ASSOCIATION_V1);
/* IKEv1 encodes multiple proposals in a single substructure
* TODO-IKEv1: Encode ESP+AH proposals in two different substructs */
- substruct = proposal_substructure_create_from_proposals(proposals);
+ substruct = proposal_substructure_create_from_proposals_v1(proposals,
+ lifetime, lifebytes, auth, mode, udp);
substruct->set_is_last_proposal(substruct, TRUE);
this->proposals->insert_last(this->proposals, substruct);
compute_length(this);
@@ -529,8 +478,8 @@ sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal,
this = (private_sa_payload_t*)sa_payload_create(SECURITY_ASSOCIATION_V1);
- substruct = proposal_substructure_create_from_proposal(
- PROPOSAL_SUBSTRUCTURE_V1, proposal);
+ substruct = proposal_substructure_create_from_proposal_v1(proposal,
+ lifetime, lifebytes, auth, mode, udp);
substruct->set_is_last_proposal(substruct, TRUE);
this->proposals->insert_last(this->proposals, substruct);
compute_length(this);
diff --git a/src/libcharon/encoding/payloads/transform_attribute.c b/src/libcharon/encoding/payloads/transform_attribute.c
index 474362fca..7e8a9c7c7 100644
--- a/src/libcharon/encoding/payloads/transform_attribute.c
+++ b/src/libcharon/encoding/payloads/transform_attribute.c
@@ -290,13 +290,28 @@ transform_attribute_t *transform_attribute_create(payload_type_t type)
* Described in header.
*/
transform_attribute_t *transform_attribute_create_value(payload_type_t type,
- transform_attribute_type_t kind, u_int16_t value)
+ transform_attribute_type_t kind, u_int64_t value)
{
transform_attribute_t *attribute;
attribute = transform_attribute_create(type);
attribute->set_attribute_type(attribute, kind);
- attribute->set_value(attribute, value);
+ if (value <= UINT16_MAX)
+ {
+ attribute->set_value(attribute, value);
+ }
+ else if (value <= UINT32_MAX)
+ {
+ u_int32_t val32;
+
+ val32 = htonl(value);
+ attribute->set_value_chunk(attribute, chunk_from_thing(val32));
+ }
+ else
+ {
+ value = htobe64(value);
+ attribute->set_value_chunk(attribute, chunk_from_thing(value));
+ }
return attribute;
}
diff --git a/src/libcharon/encoding/payloads/transform_attribute.h b/src/libcharon/encoding/payloads/transform_attribute.h
index eedb3be21..52e5d8412 100644
--- a/src/libcharon/encoding/payloads/transform_attribute.h
+++ b/src/libcharon/encoding/payloads/transform_attribute.h
@@ -163,7 +163,7 @@ struct transform_attribute_t {
transform_attribute_t *transform_attribute_create(payload_type_t type);
/**
- * Creates a two byte value attribute for a given attribute kind.
+ * Creates a two byte value or a larger attribute for a given attribute kind.
*
* @param type TRANSFORM_ATTRIBUTE or TRANSFORM_ATTRIBUTE_V1
* @param kind attribute kind
@@ -171,6 +171,6 @@ transform_attribute_t *transform_attribute_create(payload_type_t type);
* @return transform_attribute_t object
*/
transform_attribute_t *transform_attribute_create_value(payload_type_t type,
- transform_attribute_type_t kind, u_int16_t value);
+ transform_attribute_type_t kind, u_int64_t value);
#endif /** TRANSFORM_ATTRIBUTE_H_ @}*/