aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-05-23 18:44:48 +0200
committerTobias Brunner <tobias@strongswan.org>2012-05-24 15:32:27 +0200
commit7a75cae8566dbf1a42f12c9e7521aa59866f240d (patch)
tree327690aa53781c547b5641fec212743cd3968a6f /src
parent00e11bcefd04c6417196d37666ce95ea424d8261 (diff)
downloadstrongswan-7a75cae8566dbf1a42f12c9e7521aa59866f240d.tar.bz2
strongswan-7a75cae8566dbf1a42f12c9e7521aa59866f240d.tar.xz
Added support for IKEv1 IPComp proposals in proposal substructure.
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/config/proposal.c3
-rw-r--r--src/libcharon/config/proposal.h1
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.c98
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.h37
4 files changed, 129 insertions, 10 deletions
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index d3c60a469..edba0f79b 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -28,11 +28,12 @@
#include <crypto/signers/signer.h>
#include <crypto/proposal/proposal_keywords.h>
-ENUM(protocol_id_names, PROTO_NONE, PROTO_ESP,
+ENUM(protocol_id_names, PROTO_NONE, PROTO_IPCOMP,
"PROTO_NONE",
"IKE",
"AH",
"ESP",
+ "IPCOMP",
);
typedef struct private_proposal_t private_proposal_t;
diff --git a/src/libcharon/config/proposal.h b/src/libcharon/config/proposal.h
index 8f54d7e6e..fc93933e1 100644
--- a/src/libcharon/config/proposal.h
+++ b/src/libcharon/config/proposal.h
@@ -43,6 +43,7 @@ enum protocol_id_t {
PROTO_IKE = 1,
PROTO_AH = 2,
PROTO_ESP = 3,
+ PROTO_IPCOMP = 4, /* IKEv1 only */
};
/**
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index 64422ff2d..ba7182002 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -292,6 +293,15 @@ typedef enum {
IKEV1_AUTH_HYBRID_RESP_DSS = 64224,
} ikev1_auth_method_t;
+/**
+ * IKEv1 IPComp transform IDs
+ */
+typedef enum {
+ IKEV1_IPCOMP_OUI = 1,
+ IKEV1_IPCOMP_DEFLATE = 2,
+ IKEV1_IPCOMP_LZS = 3,
+} ikev1_ipcomp_transform_t;
+
METHOD(payload_t, verify, status_t,
private_proposal_substructure_t *this)
{
@@ -314,12 +324,19 @@ METHOD(payload_t, verify, status_t,
switch (this->protocol_id)
{
+ case PROTO_IPCOMP:
+ if (this->spi.len != 2)
+ {
+ DBG1(DBG_ENC, "invalid CPI length in IPCOMP proposal");
+ return FAILED;
+ }
+ break;
case PROTO_AH:
case PROTO_ESP:
if (this->spi.len != 4)
{
DBG1(DBG_ENC, "invalid SPI length in %N proposal",
- protocol_id_names, this->protocol_id);
+ protocol_id_names, this->protocol_id);
return FAILED;
}
break;
@@ -472,6 +489,35 @@ METHOD(proposal_substructure_t, get_spi, chunk_t,
return this->spi;
}
+METHOD(proposal_substructure_t, get_cpi, bool,
+ private_proposal_substructure_t *this, u_int16_t *cpi)
+{
+
+ transform_substructure_t *transform;
+ enumerator_t *enumerator;
+
+ if (this->protocol_id != PROTO_IPCOMP)
+ {
+ return FALSE;
+ }
+
+ enumerator = this->transforms->create_enumerator(this->transforms);
+ while (enumerator->enumerate(enumerator, &transform))
+ {
+ if (transform->get_transform_id(transform) == IKEV1_IPCOMP_DEFLATE)
+ {
+ if (cpi)
+ {
+ *cpi = *((u_int16_t*)this->spi.ptr);
+ }
+ enumerator->destroy(enumerator);
+ return TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return FALSE;
+}
+
/**
* Add a transform to a proposal for IKEv2
*/
@@ -1115,6 +1161,7 @@ proposal_substructure_t *proposal_substructure_create(payload_type_t type)
.create_substructure_enumerator = _create_substructure_enumerator,
.set_spi = _set_spi,
.get_spi = _get_spi,
+ .get_cpi = _get_cpi,
.get_lifetime = _get_lifetime,
.get_lifebytes = _get_lifebytes,
.get_auth_method = _get_auth_method,
@@ -1466,3 +1513,52 @@ proposal_substructure_t *proposal_substructure_create_from_proposals_v1(
return &this->public;
}
+
+/**
+ * See header.
+ */
+proposal_substructure_t *proposal_substructure_create_for_ipcomp_v1(
+ u_int32_t lifetime, u_int64_t lifebytes, u_int16_t cpi,
+ u_int8_t proposal_number)
+{
+ private_proposal_substructure_t *this;
+ transform_substructure_t *transform;
+
+
+ this = (private_proposal_substructure_t*)
+ proposal_substructure_create(PROPOSAL_SUBSTRUCTURE_V1);
+
+ /* we currently support DEFLATE only */
+ transform = transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1,
+ 1, IKEV1_IPCOMP_DEFLATE);
+
+ 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, lifetime));
+ }
+ 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);
+
+ this->spi = chunk_clone(chunk_from_thing(cpi));
+ this->spi_size = this->spi.len;
+ this->protocol_id = PROTO_IPCOMP;
+ this->proposal_number = proposal_number;
+
+ compute_length(this);
+
+ return &this->public;
+} \ No newline at end of file
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.h b/src/libcharon/encoding/payloads/proposal_substructure.h
index aefdf2f27..720f9790b 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.h
+++ b/src/libcharon/encoding/payloads/proposal_substructure.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -52,7 +53,7 @@ struct proposal_substructure_t {
/**
* get proposal number of current proposal.
*
- * @return proposal number of current proposal substructure.
+ * @return proposal number of current proposal substructure.
*/
u_int8_t (*get_proposal_number) (proposal_substructure_t *this);
@@ -67,7 +68,7 @@ struct proposal_substructure_t {
/**
* get protocol id of current proposal.
*
- * @return protocol id of current proposal substructure.
+ * @return protocol id of current proposal substructure.
*/
u_int8_t (*get_protocol_id) (proposal_substructure_t *this);
@@ -84,7 +85,7 @@ struct proposal_substructure_t {
/**
* Returns the currently set SPI of this proposal.
*
- * @return chunk_t pointing to the value
+ * @return chunk_t pointing to the value
*/
chunk_t (*get_spi) (proposal_substructure_t *this);
@@ -98,6 +99,14 @@ struct proposal_substructure_t {
void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
/**
+ * Gets the CPI of the current proposal (IKEv1 only).
+ *
+ * @param cpi the CPI if a supported algorithm is proposed
+ * @return TRUE if a supported algorithm is proposed
+ */
+ bool (*get_cpi) (proposal_substructure_t *this, u_int16_t *cpi);
+
+ /**
* Get proposals contained in a propsal_substructure_t.
*
* @param list list to add created proposals to
@@ -158,7 +167,7 @@ proposal_substructure_t *proposal_substructure_create(payload_type_t type);
* Creates an IKEv2 proposal_substructure_t from a proposal_t.
*
* @param proposal proposal to build a substruct out of it
- * @return proposal_substructure_t PROPOSAL_SUBSTRUCTURE
+ * @return proposal_substructure_t PROPOSAL_SUBSTRUCTURE
*/
proposal_substructure_t *proposal_substructure_create_from_proposal_v2(
proposal_t *proposal);
@@ -171,9 +180,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal_v2(
* @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
+ * @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,
@@ -188,10 +195,24 @@ proposal_substructure_t *proposal_substructure_create_from_proposal_v1(
* @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
+ * @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1
*/
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);
+/**
+ * Creates an IKEv1 proposal_substructure_t for IPComp with the given
+ * proposal_number (e.g. of a ESP proposal to bundle them).
+ *
+ * @param lifetime lifetime in seconds
+ * @param lifebytes lifebytes, in bytes
+ * @param cpi the CPI to be used
+ * @param proposal_number the proposal number of the proposal to be linked
+ * @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1
+ */
+proposal_substructure_t *proposal_substructure_create_for_ipcomp_v1(
+ u_int32_t lifetime, u_int64_t lifebytes, u_int16_t cpi,
+ u_int8_t proposal_number);
+
#endif /** PROPOSAL_SUBSTRUCTURE_H_ @}*/