aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/conftest/hooks/custom_proposal.c3
-rw-r--r--src/conftest/hooks/pretend_auth.c3
-rw-r--r--src/conftest/hooks/set_proposal_number.c2
-rw-r--r--src/libcharon/encoding/parser.c12
-rw-r--r--src/libcharon/encoding/payloads/encodings.h5
-rw-r--r--src/libcharon/encoding/payloads/payload.c3
-rw-r--r--src/libcharon/encoding/payloads/payload.h12
-rw-r--r--src/libcharon/encoding/payloads/sa_payload.c125
-rw-r--r--src/libcharon/encoding/payloads/sa_payload.h20
-rw-r--r--src/libcharon/sa/tasks/child_create.c6
-rw-r--r--src/libcharon/sa/tasks/ike_init.c6
11 files changed, 160 insertions, 37 deletions
diff --git a/src/conftest/hooks/custom_proposal.c b/src/conftest/hooks/custom_proposal.c
index e4acd841f..9522335b1 100644
--- a/src/conftest/hooks/custom_proposal.c
+++ b/src/conftest/hooks/custom_proposal.c
@@ -145,7 +145,8 @@ METHOD(listener_t, message, bool,
proposal->get_protocol(proposal),
proposal->get_spi(proposal));
DBG1(DBG_CFG, "injecting custom proposal: %#P", new_props);
- new = sa_payload_create_from_proposal_list(new_props);
+ new = sa_payload_create_from_proposal_list(
+ SECURITY_ASSOCIATION, new_props);
message->add_payload(message, (payload_t*)new);
new_props->destroy_offset(new_props, offsetof(proposal_t, destroy));
}
diff --git a/src/conftest/hooks/pretend_auth.c b/src/conftest/hooks/pretend_auth.c
index 4b7168cac..dd6ab9959 100644
--- a/src/conftest/hooks/pretend_auth.c
+++ b/src/conftest/hooks/pretend_auth.c
@@ -294,7 +294,8 @@ static void process_auth_response(private_pretend_auth_t *this,
if (this->proposal)
{
message->add_payload(message, (payload_t*)
- sa_payload_create_from_proposal(this->proposal));
+ sa_payload_create_from_proposal(SECURITY_ASSOCIATION,
+ this->proposal));
}
if (this->tsi)
{
diff --git a/src/conftest/hooks/set_proposal_number.c b/src/conftest/hooks/set_proposal_number.c
index a59d96b6d..32b0155cb 100644
--- a/src/conftest/hooks/set_proposal_number.c
+++ b/src/conftest/hooks/set_proposal_number.c
@@ -121,7 +121,7 @@ METHOD(listener_t, message, bool,
}
enumerator->destroy(enumerator);
}
- sa = sa_payload_create_from_proposal_list(updated);
+ sa = sa_payload_create_from_proposal_list(SECURITY_ASSOCIATION, updated);
list->destroy_offset(list, offsetof(proposal_t, destroy));
updated->destroy_offset(updated, offsetof(proposal_t, destroy));
message->add_payload(message, (payload_t*)sa);
diff --git a/src/libcharon/encoding/parser.c b/src/libcharon/encoding/parser.c
index 6309a5c3f..09b52168f 100644
--- a/src/libcharon/encoding/parser.c
+++ b/src/libcharon/encoding/parser.c
@@ -496,6 +496,18 @@ METHOD(parser_t, parse_payload, status_t,
}
break;
}
+ case PROPOSALS_V1:
+ {
+ if (payload_length < SA_PAYLOAD_V1_HEADER_LENGTH ||
+ !parse_list(this, rule_number, output + rule->offset,
+ PROPOSAL_SUBSTRUCTURE_V1,
+ payload_length - SA_PAYLOAD_V1_HEADER_LENGTH))
+ {
+ pld->destroy(pld);
+ return PARSE_ERROR;
+ }
+ break;
+ }
case TRANSFORMS:
{
if (payload_length <
diff --git a/src/libcharon/encoding/payloads/encodings.h b/src/libcharon/encoding/payloads/encodings.h
index 52af4a984..80df979cc 100644
--- a/src/libcharon/encoding/payloads/encodings.h
+++ b/src/libcharon/encoding/payloads/encodings.h
@@ -220,6 +220,11 @@ enum encoding_type_t {
PROPOSALS,
/**
+ * Same as PROPOSALS, but for IKEv1 in a SECURITY_ASSOCIATION_V1
+ */
+ PROPOSALS_V1,
+
+ /**
* Representating one or more transform substructures.
*
* The offset points to a linked_list_t pointer.
diff --git a/src/libcharon/encoding/payloads/payload.c b/src/libcharon/encoding/payloads/payload.c
index 78451c5b4..14617b4e3 100644
--- a/src/libcharon/encoding/payloads/payload.c
+++ b/src/libcharon/encoding/payloads/payload.c
@@ -156,7 +156,8 @@ payload_t *payload_create(payload_type_t type)
case HEADER:
return (payload_t*)ike_header_create();
case SECURITY_ASSOCIATION:
- return (payload_t*)sa_payload_create();
+ case SECURITY_ASSOCIATION_V1:
+ return (payload_t*)sa_payload_create(type);
case PROPOSAL_SUBSTRUCTURE:
return (payload_t*)proposal_substructure_create();
case TRANSFORM_SUBSTRUCTURE:
diff --git a/src/libcharon/encoding/payloads/payload.h b/src/libcharon/encoding/payloads/payload.h
index 021383a1d..ff1ae73a3 100644
--- a/src/libcharon/encoding/payloads/payload.h
+++ b/src/libcharon/encoding/payloads/payload.h
@@ -29,6 +29,10 @@ typedef struct payload_t payload_t;
#include <library.h>
#include <encoding/payloads/encodings.h>
+/**
+ * Domain of interpretation used by IPsec/IKEv1
+ */
+#define IKEV1_DOI_IPSEC 1
/**
* Payload-Types of an IKE message.
@@ -243,6 +247,14 @@ enum payload_type_t {
* used internally to handle a transform attribute like a payload.
*/
CONFIGURATION_ATTRIBUTE = 261,
+
+ /**
+ * PROPOSAL_SUBSTRUCTURE has a value of PRIVATE USE space.
+ *
+ * This payload type is not sent over wire and just
+ * used internally to handle a proposal substructure like a payload.
+ */
+ PROPOSAL_SUBSTRUCTURE_V1 = 262,
};
/**
diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c
index 89464ac3d..af3012623 100644
--- a/src/libcharon/encoding/payloads/sa_payload.c
+++ b/src/libcharon/encoding/payloads/sa_payload.c
@@ -22,6 +22,8 @@
#include <utils/linked_list.h>
#include <daemon.h>
+/* IKEv1 situation */
+#define SIT_IDENTITY_ONLY 1
typedef struct private_sa_payload_t private_sa_payload_t;
@@ -48,7 +50,7 @@ struct private_sa_payload_t {
/**
* Reserved bits
*/
- bool reserved[7];
+ bool reserved[8];
/**
* Length of this payload.
@@ -58,21 +60,75 @@ struct private_sa_payload_t {
/**
* Proposals in this payload are stored in a linked_list_t.
*/
- linked_list_t * proposals;
+ linked_list_t *proposals;
+
+ /**
+ * Type of this payload, V1 or V2
+ */
+ payload_type_t type;
+
+ /**
+ * IKEv1 DOI
+ */
+ u_int32_t doi;
+
+ /**
+ * IKEv1 situation
+ */
+ u_int32_t situation;
};
/**
- * Encoding rules to parse or generate a IKEv2-SA Payload
- *
- * The defined offsets are the positions in a object of type
- * private_sa_payload_t.
+ * Encoding rules for IKEv1 SA payload
*/
-encoding_rule_t sa_payload_encodings[] = {
+static encoding_rule_t encodings_v1[] = {
+ /* 1 Byte next payload type, stored in the field next_payload */
+ { U_INT_8, offsetof(private_sa_payload_t, next_payload) },
+ /* 8 reserved bits */
+ { RESERVED_BIT, offsetof(private_sa_payload_t, reserved[0]) },
+ { RESERVED_BIT, offsetof(private_sa_payload_t, reserved[1]) },
+ { RESERVED_BIT, offsetof(private_sa_payload_t, reserved[2]) },
+ { RESERVED_BIT, offsetof(private_sa_payload_t, reserved[3]) },
+ { RESERVED_BIT, offsetof(private_sa_payload_t, reserved[4]) },
+ { RESERVED_BIT, offsetof(private_sa_payload_t, reserved[5]) },
+ { RESERVED_BIT, offsetof(private_sa_payload_t, reserved[6]) },
+ { RESERVED_BIT, offsetof(private_sa_payload_t, reserved[7]) },
+ /* Length of the whole SA payload*/
+ { PAYLOAD_LENGTH, offsetof(private_sa_payload_t, payload_length) },
+ /* DOI*/
+ { U_INT_32, offsetof(private_sa_payload_t, doi) },
+ /* Situation*/
+ { U_INT_32, offsetof(private_sa_payload_t, situation) },
+ /* Proposals are stored in a proposal substructure,
+ offset points to a linked_list_t pointer */
+ { PROPOSALS_V1, offsetof(private_sa_payload_t, proposals) },
+};
+
+/*
+ 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Next Payload ! RESERVED ! Payload Length !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! DOI !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Situation !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! !
+ ~ <Proposals> ~
+ ! !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+/**
+ * Encoding rules for IKEv2 SA payload
+ */
+static encoding_rule_t encodings_v2[] = {
/* 1 Byte next payload type, stored in the field next_payload */
{ U_INT_8, offsetof(private_sa_payload_t, next_payload) },
/* the critical bit */
{ FLAG, offsetof(private_sa_payload_t, critical) },
- /* 7 Bit reserved bits, nowhere stored */
+ /* 7 Bit reserved bits */
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[0]) },
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[1]) },
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[2]) },
@@ -144,14 +200,22 @@ METHOD(payload_t, verify, status_t,
METHOD(payload_t, get_encoding_rules, void,
private_sa_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
{
- *rules = sa_payload_encodings;
- *rule_count = countof(sa_payload_encodings);
+ if (this->type == SECURITY_ASSOCIATION_V1)
+ {
+ *rules = encodings_v1;
+ *rule_count = countof(encodings_v1);
+ }
+ else
+ {
+ *rules = encodings_v2;
+ *rule_count = countof(encodings_v2);
+ }
}
METHOD(payload_t, get_type, payload_type_t,
private_sa_payload_t *this)
{
- return SECURITY_ASSOCIATION;
+ return this->type;
}
METHOD(payload_t, get_next_type, payload_type_t,
@@ -175,6 +239,11 @@ static void compute_length(private_sa_payload_t *this)
payload_t *current;
size_t length = SA_PAYLOAD_HEADER_LENGTH;
+ if (this->type == SECURITY_ASSOCIATION_V1)
+ {
+ length = SA_PAYLOAD_V1_HEADER_LENGTH;
+ }
+
enumerator = this->proposals->create_enumerator(this->proposals);
while (enumerator->enumerate(enumerator, (void **)&current))
{
@@ -270,14 +339,14 @@ METHOD2(payload_t, sa_payload_t, destroy, void,
private_sa_payload_t *this)
{
this->proposals->destroy_offset(this->proposals,
- offsetof(proposal_substructure_t, destroy));
+ offsetof(payload_t, destroy));
free(this);
}
/*
* Described in header.
*/
-sa_payload_t *sa_payload_create()
+sa_payload_t *sa_payload_create(payload_type_t type)
{
private_sa_payload_t *this;
@@ -298,41 +367,49 @@ sa_payload_t *sa_payload_create()
.destroy = _destroy,
},
.next_payload = NO_PAYLOAD,
- .payload_length = SA_PAYLOAD_HEADER_LENGTH,
.proposals = linked_list_create(),
+ .type = type,
+ /* for IKEv1 only */
+ .doi = IKEV1_DOI_IPSEC,
+ .situation = SIT_IDENTITY_ONLY,
);
+
+ compute_length(this);
+
return &this->public;
}
/*
* Described in header.
*/
-sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals)
+sa_payload_t *sa_payload_create_from_proposal_list(payload_type_t type,
+ linked_list_t *proposals)
{
- private_sa_payload_t *this;
+ sa_payload_t *this;
enumerator_t *enumerator;
proposal_t *proposal;
- this = (private_sa_payload_t*)sa_payload_create();
+ this = sa_payload_create(type);
enumerator = proposals->create_enumerator(proposals);
while (enumerator->enumerate(enumerator, &proposal))
{
- add_proposal(this, proposal);
+ this->add_proposal(this, proposal);
}
enumerator->destroy(enumerator);
- return &this->public;
+ return this;
}
/*
* Described in header.
*/
-sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal)
+sa_payload_t *sa_payload_create_from_proposal(payload_type_t type,
+ proposal_t *proposal)
{
- private_sa_payload_t *this;
+ sa_payload_t *this;
- this = (private_sa_payload_t*)sa_payload_create();
- add_proposal(this, proposal);
+ this = sa_payload_create(type);
+ this->add_proposal(this, proposal);
- return &this->public;
+ return this;
}
diff --git a/src/libcharon/encoding/payloads/sa_payload.h b/src/libcharon/encoding/payloads/sa_payload.h
index cc8c481c8..11fc774e5 100644
--- a/src/libcharon/encoding/payloads/sa_payload.h
+++ b/src/libcharon/encoding/payloads/sa_payload.h
@@ -30,12 +30,17 @@ typedef struct sa_payload_t sa_payload_t;
#include <utils/linked_list.h>
/**
- * SA_PAYLOAD length in bytes without any proposal substructure.
+ * SECURITY_ASSOCIATION length in bytes without any proposal substructure.
*/
#define SA_PAYLOAD_HEADER_LENGTH 4
/**
- * Class representing an IKEv2-SA Payload.
+ * SECURITY_ASSOCIATION_V1 length in bytes without any proposal substructure.
+ */
+#define SA_PAYLOAD_V1_HEADER_LENGTH 12
+
+/**
+ * Class representing an IKEv1 or IKEv2 SA Payload.
*
* The SA Payload format is described in RFC section 3.3.
*/
@@ -76,17 +81,20 @@ struct sa_payload_t {
/**
* Creates an empty sa_payload_t object
*
+ * @param type SECURITY_ASSOCIATION or SECURITY_ASSOCIATION_V1
* @return created sa_payload_t object
*/
-sa_payload_t *sa_payload_create(void);
+sa_payload_t *sa_payload_create(payload_type_t type);
/**
* Creates a sa_payload_t object from a list of proposals.
*
+ * @param type SECURITY_ASSOCIATION or SECURITY_ASSOCIATION_V1
* @param proposals list of proposals to build the payload from
* @return sa_payload_t object
*/
-sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
+sa_payload_t *sa_payload_create_from_proposal_list(payload_type_t type,
+ linked_list_t *proposals);
/**
* Creates a sa_payload_t object from a single proposal.
@@ -94,9 +102,11 @@ sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
* This is only for convenience. Use sa_payload_create_from_proposal_list
* if you want to add more than one proposal.
*
+ * @param type SECURITY_ASSOCIATION or SECURITY_ASSOCIATION_V1
* @param proposal proposal from which the payload should be built.
* @return sa_payload_t object
*/
-sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal);
+sa_payload_t *sa_payload_create_from_proposal(payload_type_t type,
+ proposal_t *proposal);
#endif /** SA_PAYLOAD_H_ @}*/
diff --git a/src/libcharon/sa/tasks/child_create.c b/src/libcharon/sa/tasks/child_create.c
index 67c29d31f..fdc5b520e 100644
--- a/src/libcharon/sa/tasks/child_create.c
+++ b/src/libcharon/sa/tasks/child_create.c
@@ -526,11 +526,13 @@ static void build_payloads(private_child_create_t *this, message_t *message)
/* add SA payload */
if (this->initiator)
{
- sa_payload = sa_payload_create_from_proposal_list(this->proposals);
+ sa_payload = sa_payload_create_from_proposal_list(SECURITY_ASSOCIATION,
+ this->proposals);
}
else
{
- sa_payload = sa_payload_create_from_proposal(this->proposal);
+ sa_payload = sa_payload_create_from_proposal(SECURITY_ASSOCIATION,
+ this->proposal);
}
message->add_payload(message, (payload_t*)sa_payload);
diff --git a/src/libcharon/sa/tasks/ike_init.c b/src/libcharon/sa/tasks/ike_init.c
index b8e66c7e6..911e0c2aa 100644
--- a/src/libcharon/sa/tasks/ike_init.c
+++ b/src/libcharon/sa/tasks/ike_init.c
@@ -132,7 +132,8 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
enumerator->destroy(enumerator);
}
- sa_payload = sa_payload_create_from_proposal_list(proposal_list);
+ sa_payload = sa_payload_create_from_proposal_list(SECURITY_ASSOCIATION,
+ proposal_list);
proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy));
}
else
@@ -142,7 +143,8 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
/* include SPI of new IKE_SA when we are rekeying */
this->proposal->set_spi(this->proposal, id->get_responder_spi(id));
}
- sa_payload = sa_payload_create_from_proposal(this->proposal);
+ sa_payload = sa_payload_create_from_proposal(SECURITY_ASSOCIATION,
+ this->proposal);
}
message->add_payload(message, (payload_t*)sa_payload);