summaryrefslogtreecommitdiff
path: root/src/libcharon/encoding/payloads/proposal_substructure.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/encoding/payloads/proposal_substructure.c')
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.c276
1 files changed, 122 insertions, 154 deletions
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index 53e8cf3ad..48dcfeb24 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2014 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -224,26 +224,7 @@ typedef enum {
/* FreeS/WAN proprietary */
IKEV1_ESP_ENCR_SERPENT = 252,
IKEV1_ESP_ENCR_TWOFISH = 253,
-} ikev1_esp_encr_transid_t;
-
-/**
- * IKEv1 Transform ID ESP authentication algorithm.
- */
-typedef enum {
- IKEV1_ESP_AUTH_HMAC_MD5 = 1,
- IKEV1_ESP_AUTH_HMAC_SHA = 2,
- IKEV1_ESP_AUTH_DES_MAC = 3,
- IKEV1_ESP_AUTH_KPDK = 4,
- IKEV1_ESP_AUTH_HMAC_SHA2_256 = 5,
- IKEV1_ESP_AUTH_HMAC_SHA2_384 = 6,
- IKEV1_ESP_AUTH_HMAC_SHA2_512 = 7,
- IKEV1_ESP_AUTH_HMAC_RIPEMD = 8,
- IKEV1_ESP_AUTH_AES_XCBC_MAC = 9,
- IKEV1_ESP_AUTH_SIG_RSA = 10,
- IKEV1_ESP_AUTH_AES_128_GMAC = 11,
- IKEV1_ESP_AUTH_AES_192_GMAC = 12,
- IKEV1_ESP_AUTH_AES_256_GMAC = 13,
-} ikev1_esp_auth_transid_it;
+} ikev1_esp_transid_t;
/**
* IKEv1 Transform ID AH authentication algorithm.
@@ -264,6 +245,25 @@ typedef enum {
} ikev1_ah_transid_t;
/**
+ * IKEv1 authentication algorithm.
+ */
+typedef enum {
+ IKEV1_AUTH_HMAC_MD5 = 1,
+ IKEV1_AUTH_HMAC_SHA = 2,
+ IKEV1_AUTH_DES_MAC = 3,
+ IKEV1_AUTH_KPDK = 4,
+ IKEV1_AUTH_HMAC_SHA2_256 = 5,
+ IKEV1_AUTH_HMAC_SHA2_384 = 6,
+ IKEV1_AUTH_HMAC_SHA2_512 = 7,
+ IKEV1_AUTH_HMAC_RIPEMD = 8,
+ IKEV1_AUTH_AES_XCBC_MAC = 9,
+ IKEV1_AUTH_SIG_RSA = 10,
+ IKEV1_AUTH_AES_128_GMAC = 11,
+ IKEV1_AUTH_AES_192_GMAC = 12,
+ IKEV1_AUTH_AES_256_GMAC = 13,
+} ikev1_auth_algo_t;
+
+/**
* IKEv1 ESP Encapsulation mode.
*/
typedef enum {
@@ -345,7 +345,7 @@ METHOD(payload_t, verify, status_t,
switch (this->protocol_id)
{
case PROTO_IPCOMP:
- if (this->spi.len != 2)
+ if (this->spi.len != 2 && this->spi.len != 4)
{
DBG1(DBG_ENC, "invalid CPI length in IPCOMP proposal");
return FAILED;
@@ -536,7 +536,7 @@ METHOD(proposal_substructure_t, get_cpi, bool,
{
if (cpi)
{
- *cpi = *((u_int16_t*)this->spi.ptr);
+ *cpi = htons(untoh16(this->spi.ptr + this->spi.len - 2));
}
enumerator->destroy(enumerator);
return TRUE;
@@ -620,7 +620,7 @@ static algo_map_t map_prf[] = {
/**
* ESP encryption algorithm mapping
*/
-static algo_map_t map_esp_encr[] = {
+static algo_map_t map_esp[] = {
{ IKEV1_ESP_ENCR_DES_IV64, ENCR_DES_IV64 },
{ IKEV1_ESP_ENCR_DES, ENCR_DES },
{ IKEV1_ESP_ENCR_3DES, ENCR_3DES },
@@ -646,23 +646,6 @@ static algo_map_t map_esp_encr[] = {
};
/**
- * ESP authentication algorithm mapping
- */
-static algo_map_t map_esp_auth[] = {
- { IKEV1_ESP_AUTH_HMAC_MD5, AUTH_HMAC_MD5_96 },
- { IKEV1_ESP_AUTH_HMAC_SHA, AUTH_HMAC_SHA1_96 },
- { IKEV1_ESP_AUTH_DES_MAC, AUTH_DES_MAC },
- { IKEV1_ESP_AUTH_KPDK, AUTH_KPDK_MD5 },
- { IKEV1_ESP_AUTH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 },
- { IKEV1_ESP_AUTH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 },
- { IKEV1_ESP_AUTH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 },
- { IKEV1_ESP_AUTH_AES_XCBC_MAC, AUTH_AES_XCBC_96 },
- { IKEV1_ESP_AUTH_AES_128_GMAC, AUTH_AES_128_GMAC },
- { IKEV1_ESP_AUTH_AES_192_GMAC, AUTH_AES_192_GMAC },
- { IKEV1_ESP_AUTH_AES_256_GMAC, AUTH_AES_256_GMAC },
-};
-
-/**
* AH authentication algorithm mapping
*/
static algo_map_t map_ah[] = {
@@ -679,34 +662,30 @@ static algo_map_t map_ah[] = {
};
/**
- * Get IKEv2 algorithm from IKEv1 identifier
+ * ESP/AH authentication algorithm mapping
*/
-static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
+static algo_map_t map_auth[] = {
+ { IKEV1_AUTH_HMAC_MD5, AUTH_HMAC_MD5_96 },
+ { IKEV1_AUTH_HMAC_SHA, AUTH_HMAC_SHA1_96 },
+ { IKEV1_AUTH_DES_MAC, AUTH_DES_MAC },
+ { IKEV1_AUTH_KPDK, AUTH_KPDK_MD5 },
+ { IKEV1_AUTH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 },
+ { IKEV1_AUTH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 },
+ { IKEV1_AUTH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 },
+ { IKEV1_AUTH_AES_XCBC_MAC, AUTH_AES_XCBC_96 },
+ { IKEV1_AUTH_AES_128_GMAC, AUTH_AES_128_GMAC },
+ { IKEV1_AUTH_AES_192_GMAC, AUTH_AES_192_GMAC },
+ { IKEV1_AUTH_AES_256_GMAC, AUTH_AES_256_GMAC },
+};
+
+/**
+ * Map an IKEv1 to an IKEv2 identifier
+ */
+static u_int16_t ikev2_from_ikev1(algo_map_t *map, int count, u_int16_t def,
+ u_int16_t value)
{
- algo_map_t *map;
- u_int16_t def;
- int i, count;
+ int i;
- switch (type)
- {
- case ENCRYPTION_ALGORITHM:
- map = map_encr;
- count = countof(map_encr);
- def = ENCR_UNDEFINED;
- break;
- case INTEGRITY_ALGORITHM:
- map = map_integ;
- count = countof(map_integ);
- def = AUTH_UNDEFINED;
- break;
- case PSEUDO_RANDOM_FUNCTION:
- map = map_prf;
- count = countof(map_prf);
- def = PRF_UNDEFINED;
- break;
- default:
- return 0;
- }
for (i = 0; i < count; i++)
{
if (map[i].ikev1 == value)
@@ -718,30 +697,12 @@ static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
}
/**
- * Get IKEv1 algorithm from IKEv2 identifier
+ * Map an IKEv2 to an IKEv1 identifier
*/
-static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
+static u_int16_t ikev1_from_ikev2(algo_map_t *map, int count, u_int16_t value)
{
- algo_map_t *map;
- int i, count;
+ int i;
- switch (type)
- {
- case ENCRYPTION_ALGORITHM:
- map = map_encr;
- count = countof(map_encr);
- break;
- case INTEGRITY_ALGORITHM:
- map = map_integ;
- count = countof(map_integ);
- break;
- case PSEUDO_RANDOM_FUNCTION:
- map = map_prf;
- count = countof(map_prf);
- break;
- default:
- return 0;
- }
for (i = 0; i < count; i++)
{
if (map[i].ikev2 == value)
@@ -753,87 +714,96 @@ static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
}
/**
- * Get IKEv2 algorithm from IKEv1 ESP transaction ID
+ * Get IKEv2 algorithm from IKEv1 identifier
*/
-static u_int16_t get_alg_from_ikev1_transid(protocol_id_t proto,
- transform_type_t type, u_int16_t value)
+static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
{
- algo_map_t *map;
- u_int16_t def;
- int i, count;
-
switch (type)
{
case ENCRYPTION_ALGORITHM:
- map = map_esp_encr;
- count = countof(map_esp_encr);
- def = ENCR_UNDEFINED;
- break;
+ return ikev2_from_ikev1(map_encr, countof(map_encr),
+ ENCR_UNDEFINED, value);
case INTEGRITY_ALGORITHM:
- if (proto == PROTO_ESP)
- {
- map = map_esp_auth;
- count = countof(map_esp_auth);
- }
- else
- {
- map = map_ah;
- count = countof(map_ah);
- }
- def = AUTH_UNDEFINED;
- break;
+ return ikev2_from_ikev1(map_integ, countof(map_integ),
+ AUTH_UNDEFINED, value);
+ case PSEUDO_RANDOM_FUNCTION:
+ return ikev2_from_ikev1(map_prf, countof(map_prf),
+ PRF_UNDEFINED, value);
default:
return 0;
}
- for (i = 0; i < count; i++)
+}
+
+/**
+ * Get IKEv1 algorithm from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
+{
+ switch (type)
{
- if (map[i].ikev1 == value)
- {
- return map[i].ikev2;
- }
+ case ENCRYPTION_ALGORITHM:
+ return ikev1_from_ikev2(map_encr, countof(map_encr), value);
+ case INTEGRITY_ALGORITHM:
+ return ikev1_from_ikev2(map_integ, countof(map_integ), value);
+ case PSEUDO_RANDOM_FUNCTION:
+ return ikev1_from_ikev2(map_prf, countof(map_prf), value);
+ default:
+ return 0;
}
- return def;
}
/**
- * Get IKEv1 ESP/AH transaction ID from IKEv2 identifier
+ * Get IKEv2 algorithm from IKEv1 ESP/AH transform ID
*/
-static u_int16_t get_ikev1_transid_from_alg(protocol_id_t proto,
- transform_type_t type, u_int16_t value)
+static u_int16_t get_alg_from_ikev1_transid(transform_type_t type,
+ u_int16_t value)
{
- algo_map_t *map;
- int i, count;
-
switch (type)
{
case ENCRYPTION_ALGORITHM:
- map = map_esp_encr;
- count = countof(map_esp_encr);
- break;
+ return ikev2_from_ikev1(map_esp, countof(map_esp),
+ ENCR_UNDEFINED, value);
case INTEGRITY_ALGORITHM:
- if (proto == PROTO_ESP)
- {
- map = map_esp_auth;
- count = countof(map_esp_auth);
- }
- else
- {
- map = map_ah;
- count = countof(map_ah);
- }
- break;
+ return ikev2_from_ikev1(map_ah, countof(map_ah),
+ AUTH_UNDEFINED, value);
default:
return 0;
}
- for (i = 0; i < count; i++)
+}
+
+/**
+ * Get IKEv1 ESP/AH transform ID from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_transid_from_alg(transform_type_t type,
+ u_int16_t value)
+{
+ switch (type)
{
- if (map[i].ikev2 == value)
- {
- return map[i].ikev1;
- }
+ case ENCRYPTION_ALGORITHM:
+ return ikev1_from_ikev2(map_esp, countof(map_esp), value);
+ case INTEGRITY_ALGORITHM:
+ return ikev1_from_ikev2(map_ah, countof(map_ah), value);
+ default:
+ return 0;
}
- return 0;
}
+
+/**
+ * Get IKEv1 authentication algorithm from IKEv2 identifier
+ */
+static u_int16_t get_alg_from_ikev1_auth(u_int16_t value)
+{
+ return ikev2_from_ikev1(map_auth, countof(map_auth), AUTH_UNDEFINED, value);
+}
+
+/**
+ * Get IKEv1 authentication algorithm from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_auth_from_alg(u_int16_t value)
+{
+ return ikev1_from_ikev2(map_auth, countof(map_auth), value);
+}
+
/**
* Get IKEv1 authentication attribute from auth_method_t
*/
@@ -971,8 +941,7 @@ static void add_to_proposal_v1(proposal_t *proposal,
break;
case TATTR_PH2_AUTH_ALGORITHM:
proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM,
- get_alg_from_ikev1_transid(proto, INTEGRITY_ALGORITHM,
- value), 0);
+ get_alg_from_ikev1_auth(value), 0);
break;
case TATTR_PH2_GROUP:
proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
@@ -989,7 +958,7 @@ static void add_to_proposal_v1(proposal_t *proposal,
NO_EXT_SEQ_NUMBERS, 0);
if (proto == PROTO_ESP)
{
- encr = get_alg_from_ikev1_transid(proto, ENCRYPTION_ALGORITHM,
+ encr = get_alg_from_ikev1_transid(ENCRYPTION_ALGORITHM,
transform->get_transform_id(transform));
if (encr)
{
@@ -1354,19 +1323,17 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this,
ipsec_mode_t mode, encap_t udp, int number)
{
transform_substructure_t *transform = NULL;
- u_int16_t alg, key_size;
+ u_int16_t alg, transid, key_size;
enumerator_t *enumerator;
- protocol_id_t proto;
- proto = proposal->get_protocol(proposal);
enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM);
if (enumerator->enumerate(enumerator, &alg, &key_size))
{
- alg = get_ikev1_transid_from_alg(proto, ENCRYPTION_ALGORITHM, alg);
- if (alg)
+ transid = get_ikev1_transid_from_alg(ENCRYPTION_ALGORITHM, alg);
+ if (transid)
{
transform = transform_substructure_create_type(
- PLV1_TRANSFORM_SUBSTRUCTURE, number, alg);
+ PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
if (key_size)
{
transform->add_transform_attribute(transform,
@@ -1380,13 +1347,14 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this,
enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM);
if (enumerator->enumerate(enumerator, &alg, &key_size))
{
- alg = get_ikev1_transid_from_alg(proto, INTEGRITY_ALGORITHM, alg);
- if (alg)
+ transid = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg);
+ alg = get_ikev1_auth_from_alg(alg);
+ if (transid && alg)
{
if (!transform)
{
transform = transform_substructure_create_type(
- PLV1_TRANSFORM_SUBSTRUCTURE, number, alg);
+ PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
}
transform->add_transform_attribute(transform,
transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,