summaryrefslogtreecommitdiff
path: root/src/charon/config/proposal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/config/proposal.c')
-rw-r--r--src/charon/config/proposal.c103
1 files changed, 66 insertions, 37 deletions
diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c
index dcab8cbdd..cff9859c1 100644
--- a/src/charon/config/proposal.c
+++ b/src/charon/config/proposal.c
@@ -144,39 +144,6 @@ static void add_algorithm(private_proposal_t *this, transform_type_t type, u_int
}
/**
- * Implements proposal_t.get_algorithm.
- */
-static bool get_algorithm(private_proposal_t *this, transform_type_t type, algorithm_t** algo)
-{
- linked_list_t *list;
- switch (type)
- {
- case ENCRYPTION_ALGORITHM:
- list = this->encryption_algos;
- break;
- case INTEGRITY_ALGORITHM:
- list = this->integrity_algos;
- break;
- case PSEUDO_RANDOM_FUNCTION:
- list = this->prf_algos;
- break;
- case DIFFIE_HELLMAN_GROUP:
- list = this->dh_groups;
- break;
- case EXTENDED_SEQUENCE_NUMBERS:
- list = this->esns;
- break;
- default:
- return FALSE;
- }
- if (list->get_first(list, (void**)algo) != SUCCESS)
- {
- return FALSE;
- }
- return TRUE;
-}
-
-/**
* Implements proposal_t.create_algorithm_iterator.
*/
static iterator_t *create_algorithm_iterator(private_proposal_t *this, transform_type_t type)
@@ -200,6 +167,50 @@ static iterator_t *create_algorithm_iterator(private_proposal_t *this, transform
}
/**
+ * Implements proposal_t.get_algorithm.
+ */
+static bool get_algorithm(private_proposal_t *this, transform_type_t type, algorithm_t** algo)
+{
+ iterator_t *iterator = create_algorithm_iterator(this, type);
+ if (iterator->iterate(iterator, (void**)algo))
+ {
+ iterator->destroy(iterator);
+ return TRUE;
+ }
+ iterator->destroy(iterator);
+ return FALSE;
+}
+
+/**
+ * Implements proposal_t.has_dh_group
+ */
+static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group)
+{
+ algorithm_t *current;
+ iterator_t *iterator;
+ bool result = FALSE;
+
+ iterator = this->dh_groups->create_iterator(this->dh_groups, TRUE);
+ if (iterator->get_count(iterator))
+ {
+ while (iterator->iterate(iterator, (void**)&current))
+ {
+ if (current->algorithm == group)
+ {
+ result = TRUE;
+ break;
+ }
+ }
+ }
+ else if (group == MODP_NONE)
+ {
+ result = TRUE;
+ }
+ iterator->destroy(iterator);
+ return result;
+}
+
+/**
* Find a matching alg/keysize in two linked lists
*/
static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add, u_int16_t *alg, size_t *key_size)
@@ -399,6 +410,10 @@ static proposal_t *clone_(private_proposal_t *this)
return &clone->public;
}
+/**
+ * add a algorithm identified by a string to the proposal.
+ * TODO: we could use gperf here.
+ */
static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
{
if (strncmp(alg.ptr, "null", alg.len) == 0)
@@ -443,8 +458,9 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
{
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA1, 0);
}
- }
- else if (strncmp(alg.ptr, "sha256", alg.len) == 0)
+ }
+ else if (strncmp(alg.ptr, "sha256", alg.len) == 0 ||
+ strncmp(alg.ptr, "sha2_256", alg.len) == 0)
{
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0);
if (this->protocol == PROTO_IKE)
@@ -452,7 +468,8 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_256, 0);
}
}
- else if (strncmp(alg.ptr, "sha384", alg.len) == 0)
+ else if (strncmp(alg.ptr, "sha384", alg.len) == 0 ||
+ strncmp(alg.ptr, "sha2_384", alg.len) == 0)
{
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0);
if (this->protocol == PROTO_IKE)
@@ -460,7 +477,8 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_384, 0);
}
}
- else if (strncmp(alg.ptr, "sha512", alg.len) == 0)
+ else if (strncmp(alg.ptr, "sha512", alg.len) == 0 ||
+ strncmp(alg.ptr, "sha2_512", alg.len) == 0)
{
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0);
if (this->protocol == PROTO_IKE)
@@ -476,6 +494,14 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 0);
}
}
+ else if (strncmp(alg.ptr, "aesxcbc", alg.len) == 0)
+ {
+ add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
+ if (this->protocol == PROTO_IKE)
+ {
+ add_algorithm(this, PSEUDO_RANDOM_FUNCTION, AUTH_AES_XCBC_96, 0);
+ }
+ }
else if (strncmp(alg.ptr, "modp768", alg.len) == 0)
{
add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0);
@@ -530,6 +556,7 @@ proposal_t *proposal_create(protocol_id_t protocol)
this->public.add_algorithm = (void (*)(proposal_t*,transform_type_t,u_int16_t,size_t))add_algorithm;
this->public.create_algorithm_iterator = (iterator_t* (*)(proposal_t*,transform_type_t))create_algorithm_iterator;
this->public.get_algorithm = (bool (*)(proposal_t*,transform_type_t,algorithm_t**))get_algorithm;
+ this->public.has_dh_group = (bool (*)(proposal_t*,diffie_hellman_group_t))has_dh_group;
this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*))select_proposal;
this->public.get_protocol = (protocol_id_t(*)(proposal_t*))get_protocol;
this->public.set_spi = (void(*)(proposal_t*,u_int64_t))set_spi;
@@ -586,11 +613,13 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES, 0);
add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256);
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
+ add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
break;
case PROTO_AH:
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
+ add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
break;