diff options
Diffstat (limited to 'src/libcharon/encoding/payloads/proposal_substructure.c')
-rw-r--r-- | src/libcharon/encoding/payloads/proposal_substructure.c | 276 |
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, |