diff options
Diffstat (limited to 'src/charon/config/proposal.c')
-rw-r--r-- | src/charon/config/proposal.c | 945 |
1 files changed, 0 insertions, 945 deletions
diff --git a/src/charon/config/proposal.c b/src/charon/config/proposal.c deleted file mode 100644 index 6b3500b6e..000000000 --- a/src/charon/config/proposal.c +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Copyright (C) 2008-2009 Tobias Brunner - * Copyright (C) 2006 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include <string.h> - -#include "proposal.h" - -#include <daemon.h> -#include <utils/linked_list.h> -#include <utils/identification.h> -#include <utils/lexparser.h> -#include <crypto/transform.h> -#include <crypto/prfs/prf.h> -#include <crypto/crypters/crypter.h> -#include <crypto/signers/signer.h> -#include <crypto/proposal/proposal_keywords.h> - -ENUM(protocol_id_names, PROTO_NONE, PROTO_ESP, - "PROTO_NONE", - "IKE", - "AH", - "ESP", -); - -ENUM(extended_sequence_numbers_names, NO_EXT_SEQ_NUMBERS, EXT_SEQ_NUMBERS, - "NO_EXT_SEQ", - "EXT_SEQ", -); - -typedef struct private_proposal_t private_proposal_t; -typedef struct algorithm_t algorithm_t; - -/** - * Private data of an proposal_t object - */ -struct private_proposal_t { - - /** - * Public part - */ - proposal_t public; - - /** - * protocol (ESP or AH) - */ - protocol_id_t protocol; - - /** - * priority ordered list of encryption algorithms - */ - linked_list_t *encryption_algos; - - /** - * priority ordered list of integrity algorithms - */ - linked_list_t *integrity_algos; - - /** - * priority ordered list of pseudo random functions - */ - linked_list_t *prf_algos; - - /** - * priority ordered list of dh groups - */ - linked_list_t *dh_groups; - - /** - * priority ordered list of extended sequence number flags - */ - linked_list_t *esns; - - /** - * senders SPI - */ - u_int64_t spi; -}; - -/** - * Struct used to store different kinds of algorithms. - */ -struct algorithm_t { - /** - * Value from an encryption_algorithm_t/integrity_algorithm_t/... - */ - u_int16_t algorithm; - - /** - * the associated key size in bits, or zero if not needed - */ - u_int16_t key_size; -}; - -/** - * Add algorithm/keysize to a algorithm list - */ -static void add_algo(linked_list_t *list, u_int16_t algo, u_int16_t key_size) -{ - algorithm_t *algo_key; - - algo_key = malloc_thing(algorithm_t); - algo_key->algorithm = algo; - algo_key->key_size = key_size; - list->insert_last(list, (void*)algo_key); -} - -/** - * Implements proposal_t.add_algorithm - */ -static void add_algorithm(private_proposal_t *this, transform_type_t type, - u_int16_t algo, u_int16_t key_size) -{ - switch (type) - { - case ENCRYPTION_ALGORITHM: - add_algo(this->encryption_algos, algo, key_size); - break; - case INTEGRITY_ALGORITHM: - add_algo(this->integrity_algos, algo, key_size); - break; - case PSEUDO_RANDOM_FUNCTION: - add_algo(this->prf_algos, algo, key_size); - break; - case DIFFIE_HELLMAN_GROUP: - add_algo(this->dh_groups, algo, 0); - break; - case EXTENDED_SEQUENCE_NUMBERS: - add_algo(this->esns, algo, 0); - break; - default: - break; - } -} - -/** - * filter function for peer configs - */ -static bool alg_filter(void *null, algorithm_t **in, u_int16_t *alg, - void **unused, u_int16_t *key_size) -{ - algorithm_t *algo = *in; - *alg = algo->algorithm; - if (key_size) - { - *key_size = algo->key_size; - } - return TRUE; -} - -/** - * Implements proposal_t.create_enumerator. - */ -static enumerator_t *create_enumerator(private_proposal_t *this, - transform_type_t type) -{ - 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 NULL; - } - return enumerator_create_filter(list->create_enumerator(list), - (void*)alg_filter, NULL, NULL); -} - -/** - * Implements proposal_t.get_algorithm. - */ -static bool get_algorithm(private_proposal_t *this, transform_type_t type, - u_int16_t *alg, u_int16_t *key_size) -{ - enumerator_t *enumerator; - bool found = FALSE; - - enumerator = create_enumerator(this, type); - if (enumerator->enumerate(enumerator, alg, key_size)) - { - found = TRUE; - } - enumerator->destroy(enumerator); - return found; -} - -/** - * Implements proposal_t.has_dh_group - */ -static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group) -{ - bool result = FALSE; - - if (this->dh_groups->get_count(this->dh_groups)) - { - algorithm_t *current; - enumerator_t *enumerator; - - enumerator = this->dh_groups->create_enumerator(this->dh_groups); - while (enumerator->enumerate(enumerator, (void**)¤t)) - { - if (current->algorithm == group) - { - result = TRUE; - break; - } - } - enumerator->destroy(enumerator); - } - else if (group == MODP_NONE) - { - result = TRUE; - } - return result; -} - -/** - * Implementation of proposal_t.strip_dh. - */ -static void strip_dh(private_proposal_t *this) -{ - algorithm_t *alg; - - while (this->dh_groups->remove_last(this->dh_groups, (void**)&alg) == SUCCESS) - { - free(alg); - } -} - -/** - * Returns true if the given alg is an authenticated encryption algorithm - */ -static bool is_authenticated_encryption(u_int16_t alg) -{ - switch(alg) - { - case ENCR_AES_CCM_ICV8: - case ENCR_AES_CCM_ICV12: - case ENCR_AES_CCM_ICV16: - case ENCR_AES_GCM_ICV8: - case ENCR_AES_GCM_ICV12: - case ENCR_AES_GCM_ICV16: - case ENCR_CAMELLIA_CCM_ICV8: - case ENCR_CAMELLIA_CCM_ICV12: - case ENCR_CAMELLIA_CCM_ICV16: - return TRUE; - } - return FALSE; -} - -/** - * Find a matching alg/keysize in two linked lists - */ -static bool select_algo(linked_list_t *first, linked_list_t *second, bool priv, - bool *add, u_int16_t *alg, size_t *key_size) -{ - enumerator_t *e1, *e2; - algorithm_t *alg1, *alg2; - - /* if in both are zero algorithms specified, we HAVE a match */ - if (first->get_count(first) == 0 && second->get_count(second) == 0) - { - *add = FALSE; - return TRUE; - } - - e1 = first->create_enumerator(first); - e2 = second->create_enumerator(second); - /* compare algs, order of algs in "first" is preferred */ - while (e1->enumerate(e1, &alg1)) - { - e2->destroy(e2); - e2 = second->create_enumerator(second); - while (e2->enumerate(e2, &alg2)) - { - if (alg1->algorithm == alg2->algorithm && - alg1->key_size == alg2->key_size) - { - if (!priv && alg1->algorithm >= 1024) - { - /* accept private use algorithms only if requested */ - DBG1(DBG_CFG, "an algorithm from private space would match, " - "but peer implementation is unknown, skipped"); - continue; - } - /* ok, we have an algorithm */ - *alg = alg1->algorithm; - *key_size = alg1->key_size; - *add = TRUE; - e1->destroy(e1); - e2->destroy(e2); - return TRUE; - } - } - } - /* no match in all comparisons */ - e1->destroy(e1); - e2->destroy(e2); - return FALSE; -} - -/** - * Implements proposal_t.select. - */ -static proposal_t *select_proposal(private_proposal_t *this, - private_proposal_t *other, bool private) -{ - proposal_t *selected; - u_int16_t algo; - size_t key_size; - bool add; - - DBG2(DBG_CFG, "selecting proposal:"); - - /* check protocol */ - if (this->protocol != other->protocol) - { - DBG2(DBG_CFG, " protocol mismatch, skipping"); - return NULL; - } - - selected = proposal_create(this->protocol); - - /* select encryption algorithm */ - if (select_algo(this->encryption_algos, other->encryption_algos, private, - &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, ENCRYPTION_ALGORITHM, - algo, key_size); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, ENCRYPTION_ALGORITHM); - return NULL; - } - /* select integrity algorithm */ - if (!is_authenticated_encryption(algo)) - { - if (select_algo(this->integrity_algos, other->integrity_algos, private, - &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, INTEGRITY_ALGORITHM, - algo, key_size); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, INTEGRITY_ALGORITHM); - return NULL; - } - } - /* select prf algorithm */ - if (select_algo(this->prf_algos, other->prf_algos, private, - &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, PSEUDO_RANDOM_FUNCTION, - algo, key_size); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, PSEUDO_RANDOM_FUNCTION); - return NULL; - } - /* select a DH-group */ - if (select_algo(this->dh_groups, other->dh_groups, private, - &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, DIFFIE_HELLMAN_GROUP, algo, 0); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, DIFFIE_HELLMAN_GROUP); - return NULL; - } - /* select if we use ESNs (has no private use space) */ - if (select_algo(this->esns, other->esns, TRUE, &add, &algo, &key_size)) - { - if (add) - { - selected->add_algorithm(selected, EXTENDED_SEQUENCE_NUMBERS, algo, 0); - } - } - else - { - selected->destroy(selected); - DBG2(DBG_CFG, " no acceptable %N found", - transform_type_names, EXTENDED_SEQUENCE_NUMBERS); - return NULL; - } - DBG2(DBG_CFG, " proposal matches"); - - /* apply SPI from "other" */ - selected->set_spi(selected, other->spi); - - /* everything matched, return new proposal */ - return selected; -} - -/** - * Implements proposal_t.get_protocols. - */ -static protocol_id_t get_protocol(private_proposal_t *this) -{ - return this->protocol; -} - -/** - * Implements proposal_t.set_spi. - */ -static void set_spi(private_proposal_t *this, u_int64_t spi) -{ - this->spi = spi; -} - -/** - * Implements proposal_t.get_spi. - */ -static u_int64_t get_spi(private_proposal_t *this) -{ - return this->spi; -} - -/** - * Clone a algorithm list - */ -static void clone_algo_list(linked_list_t *list, linked_list_t *clone_list) -{ - algorithm_t *algo, *clone_algo; - enumerator_t *enumerator; - - enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, &algo)) - { - clone_algo = malloc_thing(algorithm_t); - memcpy(clone_algo, algo, sizeof(algorithm_t)); - clone_list->insert_last(clone_list, (void*)clone_algo); - } - enumerator->destroy(enumerator); -} - -/** - * check if an algorithm list equals - */ -static bool algo_list_equals(linked_list_t *l1, linked_list_t *l2) -{ - enumerator_t *e1, *e2; - algorithm_t *alg1, *alg2; - bool equals = TRUE; - - if (l1->get_count(l1) != l2->get_count(l2)) - { - return FALSE; - } - - e1 = l1->create_enumerator(l1); - e2 = l2->create_enumerator(l2); - while (e1->enumerate(e1, &alg1) && e2->enumerate(e2, &alg2)) - { - if (alg1->algorithm != alg2->algorithm || - alg1->key_size != alg2->key_size) - { - equals = FALSE; - break; - } - } - e1->destroy(e1); - e2->destroy(e2); - return equals; -} - -/** - * Implementation of proposal_t.equals. - */ -static bool equals(private_proposal_t *this, private_proposal_t *other) -{ - if (this == other) - { - return TRUE; - } - if (this->public.equals != other->public.equals) - { - return FALSE; - } - return ( - algo_list_equals(this->encryption_algos, other->encryption_algos) && - algo_list_equals(this->integrity_algos, other->integrity_algos) && - algo_list_equals(this->prf_algos, other->prf_algos) && - algo_list_equals(this->dh_groups, other->dh_groups) && - algo_list_equals(this->esns, other->esns)); -} - -/** - * Implements proposal_t.clone - */ -static proposal_t *clone_(private_proposal_t *this) -{ - private_proposal_t *clone = (private_proposal_t*)proposal_create(this->protocol); - - clone_algo_list(this->encryption_algos, clone->encryption_algos); - clone_algo_list(this->integrity_algos, clone->integrity_algos); - clone_algo_list(this->prf_algos, clone->prf_algos); - clone_algo_list(this->dh_groups, clone->dh_groups); - clone_algo_list(this->esns, clone->esns); - - clone->spi = this->spi; - - return &clone->public; -} - -/** - * Checks the proposal read from a string. - */ -static void check_proposal(private_proposal_t *this) -{ - enumerator_t *e; - algorithm_t *alg; - bool all_aead = TRUE; - - e = this->encryption_algos->create_enumerator(this->encryption_algos); - while (e->enumerate(e, &alg)) - { - if (!is_authenticated_encryption(alg->algorithm)) - { - all_aead = FALSE; - break; - } - } - e->destroy(e); - - if (all_aead) - { - /* if all encryption algorithms in the proposal are authenticated encryption - * algorithms we MUST NOT propose any integrity algorithms */ - while (this->integrity_algos->remove_last(this->integrity_algos, - (void**)&alg) == SUCCESS) - { - free(alg); - } - } -} - -/** - * add a algorithm identified by a string to the proposal. - */ -static status_t add_string_algo(private_proposal_t *this, chunk_t alg) -{ - const proposal_token_t *token = proposal_get_token(alg.ptr, alg.len); - - if (token == NULL) - { - return FAILED; - } - - add_algorithm(this, token->type, token->algorithm, token->keysize); - - if (this->protocol == PROTO_IKE && token->type == INTEGRITY_ALGORITHM) - { - pseudo_random_function_t prf; - - switch (token->algorithm) - { - case AUTH_HMAC_SHA1_96: - prf = PRF_HMAC_SHA1; - break; - case AUTH_HMAC_SHA2_256_128: - prf = PRF_HMAC_SHA2_256; - break; - case AUTH_HMAC_SHA2_384_192: - prf = PRF_HMAC_SHA2_384; - break; - case AUTH_HMAC_SHA2_512_256: - prf = PRF_HMAC_SHA2_512; - break; - case AUTH_HMAC_MD5_96: - prf = PRF_HMAC_MD5; - break; - case AUTH_AES_XCBC_96: - prf = PRF_AES128_XCBC; - break; - default: - prf = PRF_UNDEFINED; - } - if (prf != PRF_UNDEFINED) - { - add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0); - } - } - return SUCCESS; -} - -/** - * print all algorithms of a kind to buffer - */ -static int print_alg(private_proposal_t *this, char **dst, size_t *len, - u_int kind, void *names, bool *first) -{ - enumerator_t *enumerator; - size_t written = 0; - u_int16_t alg, size; - - enumerator = create_enumerator(this, kind); - while (enumerator->enumerate(enumerator, &alg, &size)) - { - if (*first) - { - written += print_in_hook(*dst, *len, "%N", names, alg); - *first = FALSE; - } - else - { - written += print_in_hook(*dst, *len, "/%N", names, alg); - } - if (size) - { - written += print_in_hook(*dst, *len, "_%u", size); - } - } - enumerator->destroy(enumerator); - return written; -} - -/** - * Described in header. - */ -int proposal_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec, - const void *const *args) -{ - private_proposal_t *this = *((private_proposal_t**)(args[0])); - linked_list_t *list = *((linked_list_t**)(args[0])); - enumerator_t *enumerator; - size_t written = 0; - bool first = TRUE; - - if (this == NULL) - { - return print_in_hook(dst, len, "(null)"); - } - - if (spec->hash) - { - enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, &this)) - { /* call recursivly */ - if (first) - { - written += print_in_hook(dst, len, "%P", this); - first = FALSE; - } - else - { - written += print_in_hook(dst, len, ", %P", this); - } - } - enumerator->destroy(enumerator); - return written; - } - - written = print_in_hook(dst, len, "%N:", protocol_id_names, this->protocol); - written += print_alg(this, &dst, &len, ENCRYPTION_ALGORITHM, - encryption_algorithm_names, &first); - written += print_alg(this, &dst, &len, INTEGRITY_ALGORITHM, - integrity_algorithm_names, &first); - written += print_alg(this, &dst, &len, PSEUDO_RANDOM_FUNCTION, - pseudo_random_function_names, &first); - written += print_alg(this, &dst, &len, DIFFIE_HELLMAN_GROUP, - diffie_hellman_group_names, &first); - written += print_alg(this, &dst, &len, EXTENDED_SEQUENCE_NUMBERS, - extended_sequence_numbers_names, &first); - return written; -} - -/** - * Implements proposal_t.destroy. - */ -static void destroy(private_proposal_t *this) -{ - this->encryption_algos->destroy_function(this->encryption_algos, free); - this->integrity_algos->destroy_function(this->integrity_algos, free); - this->prf_algos->destroy_function(this->prf_algos, free); - this->dh_groups->destroy_function(this->dh_groups, free); - this->esns->destroy_function(this->esns, free); - free(this); -} - -/* - * Describtion in header-file - */ -proposal_t *proposal_create(protocol_id_t protocol) -{ - private_proposal_t *this = malloc_thing(private_proposal_t); - - this->public.add_algorithm = (void (*)(proposal_t*,transform_type_t,u_int16_t,u_int16_t))add_algorithm; - this->public.create_enumerator = (enumerator_t* (*)(proposal_t*,transform_type_t))create_enumerator; - this->public.get_algorithm = (bool (*)(proposal_t*,transform_type_t,u_int16_t*,u_int16_t*))get_algorithm; - this->public.has_dh_group = (bool (*)(proposal_t*,diffie_hellman_group_t))has_dh_group; - this->public.strip_dh = (void(*)(proposal_t*))strip_dh; - this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*,bool))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; - this->public.get_spi = (u_int64_t(*)(proposal_t*))get_spi; - this->public.equals = (bool(*)(proposal_t*, proposal_t *other))equals; - this->public.clone = (proposal_t*(*)(proposal_t*))clone_; - this->public.destroy = (void(*)(proposal_t*))destroy; - - this->spi = 0; - this->protocol = protocol; - - this->encryption_algos = linked_list_create(); - this->integrity_algos = linked_list_create(); - this->prf_algos = linked_list_create(); - this->dh_groups = linked_list_create(); - this->esns = linked_list_create(); - - return &this->public; -} - -/** - * Add supported IKE algorithms to proposal - */ -static void proposal_add_supported_ike(private_proposal_t *this) -{ - enumerator_t *enumerator; - encryption_algorithm_t encryption; - integrity_algorithm_t integrity; - pseudo_random_function_t prf; - diffie_hellman_group_t group; - - enumerator = lib->crypto->create_crypter_enumerator(lib->crypto); - while (enumerator->enumerate(enumerator, &encryption)) - { - switch (encryption) - { - case ENCR_AES_CBC: - /* we assume that we support all AES sizes */ - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128); - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192); - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256); - break; - case ENCR_3DES: - case ENCR_AES_CTR: - case ENCR_AES_CCM_ICV8: - case ENCR_AES_CCM_ICV12: - case ENCR_AES_CCM_ICV16: - case ENCR_AES_GCM_ICV8: - case ENCR_AES_GCM_ICV12: - case ENCR_AES_GCM_ICV16: - add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 0); - break; - case ENCR_DES: - /* no, thanks */ - break; - default: - break; - } - } - enumerator->destroy(enumerator); - - enumerator = lib->crypto->create_signer_enumerator(lib->crypto); - while (enumerator->enumerate(enumerator, &integrity)) - { - switch (integrity) - { - case AUTH_HMAC_SHA1_96: - case AUTH_HMAC_SHA2_256_128: - case AUTH_HMAC_SHA2_384_192: - case AUTH_HMAC_SHA2_512_256: - case AUTH_HMAC_MD5_96: - case AUTH_AES_XCBC_96: - add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0); - break; - default: - break; - } - } - enumerator->destroy(enumerator); - - enumerator = lib->crypto->create_prf_enumerator(lib->crypto); - while (enumerator->enumerate(enumerator, &prf)) - { - switch (prf) - { - case PRF_HMAC_SHA1: - case PRF_HMAC_SHA2_256: - case PRF_HMAC_SHA2_384: - case PRF_HMAC_SHA2_512: - case PRF_HMAC_MD5: - case PRF_AES128_XCBC: - add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0); - break; - default: - break; - } - } - enumerator->destroy(enumerator); - - enumerator = lib->crypto->create_dh_enumerator(lib->crypto); - while (enumerator->enumerate(enumerator, &group)) - { - switch (group) - { - case MODP_NULL: - /* only for testing purposes */ - break; - case MODP_768_BIT: - /* weak */ - break; - case MODP_1024_BIT: - case MODP_1536_BIT: - case MODP_2048_BIT: - case MODP_4096_BIT: - case MODP_8192_BIT: - case ECP_256_BIT: - case ECP_384_BIT: - case ECP_521_BIT: - case ECP_192_BIT: - case ECP_224_BIT: - add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0); - break; - default: - break; - } - } - enumerator->destroy(enumerator); -} - -/* - * Describtion in header-file - */ -proposal_t *proposal_create_default(protocol_id_t protocol) -{ - private_proposal_t *this = (private_proposal_t*)proposal_create(protocol); - - switch (protocol) - { - case PROTO_IKE: - proposal_add_supported_ike(this); - break; - case PROTO_ESP: - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192); - add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256); - 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; - default: - break; - } - return &this->public; -} - -/* - * Describtion in header-file - */ -proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs) -{ - private_proposal_t *this = (private_proposal_t*)proposal_create(protocol); - chunk_t string = {(void*)algs, strlen(algs)}; - chunk_t alg; - status_t status = SUCCESS; - - eat_whitespace(&string); - if (string.len < 1) - { - destroy(this); - return NULL; - } - - /* get all tokens, separated by '-' */ - while (extract_token(&alg, '-', &string)) - { - status |= add_string_algo(this, alg); - } - if (string.len) - { - status |= add_string_algo(this, string); - } - if (status != SUCCESS) - { - destroy(this); - return NULL; - } - - check_proposal(this); - - if (protocol == PROTO_AH || protocol == PROTO_ESP) - { - add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); - } - return &this->public; -} |