diff options
Diffstat (limited to 'src/pluto/alg_info.c')
-rw-r--r-- | src/pluto/alg_info.c | 1539 |
1 files changed, 496 insertions, 1043 deletions
diff --git a/src/pluto/alg_info.c b/src/pluto/alg_info.c index cd02d2358..a85a18905 100644 --- a/src/pluto/alg_info.c +++ b/src/pluto/alg_info.c @@ -1,6 +1,7 @@ /* * Algorithm info parsing and creation functions - * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> + * Copyright (C) JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> + * Copyright (C) 2009 Andreas Steffen - 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 @@ -11,8 +12,6 @@ * 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. - * - * RCSID $Id: alg_info.c 3846 2008-04-18 17:01:45Z andreas $ */ #include <stddef.h> @@ -27,390 +26,187 @@ #include <ctype.h> #include <freeswan.h> -#include <ipsec_policy.h> #include <pfkeyv2.h> +#include <utils.h> +#include <utils/lexparser.h> +#include <crypto/diffie_hellman.h> +#include <crypto/transform.h> +#include <crypto/proposal/proposal_keywords.h> + + #include "alg_info.h" #include "constants.h" -#ifndef NO_PLUTO #include "defs.h" #include "log.h" #include "whack.h" -#include "sha1.h" -#include "md5.h" #include "crypto.h" #include "kernel_alg.h" #include "ike_alg.h" -#else -/* - * macros/functions for compilation without pluto (eg: spi for manual conns) - */ -#include <assert.h> -#define passert(x) assert(x) -extern int debug; /* eg: spi.c */ -#define DBG(cond, action) { if (debug) { action ; } } -#define DBG_log(x, args...) fprintf(stderr, x "\n" , ##args); -#define RC_LOG_SERIOUS -#define loglog(x, args...) fprintf(stderr, ##args); -#define alloc_thing(thing, name) alloc_bytes(sizeof (thing), name) -void * alloc_bytes(size_t size, const char *name) { - void *p=malloc(size); - if (p == NULL) - fprintf(stderr, "unable to malloc %lu bytes for %s", - (unsigned long) size, name); - memset(p, '\0', size); - return p; -} -#define pfreeany(ptr) free(ptr) -#endif /* NO_PLUTO */ /* * sadb/ESP aa attrib converters */ -int -alg_info_esp_aa2sadb(int auth) -{ - int sadb_aalg = 0; - - switch(auth) { - case AUTH_ALGORITHM_HMAC_MD5: - case AUTH_ALGORITHM_HMAC_SHA1: - sadb_aalg = auth + 1; - break; - case AUTH_ALGORITHM_HMAC_SHA2_256: - case AUTH_ALGORITHM_HMAC_SHA2_384: - case AUTH_ALGORITHM_HMAC_SHA2_512: - case AUTH_ALGORITHM_HMAC_RIPEMD: - sadb_aalg = auth; - break; - default: - /* loose ... */ - sadb_aalg = auth; - } - return sadb_aalg; -} - -int /* __attribute__ ((unused)) */ -alg_info_esp_sadb2aa(int sadb_aalg) -{ - int auth = 0; - - switch(sadb_aalg) { - case SADB_AALG_MD5HMAC: - case SADB_AALG_SHA1HMAC: - auth = sadb_aalg - 1; - break; - /* since they are the same ... :) */ - case AUTH_ALGORITHM_HMAC_SHA2_256: - case AUTH_ALGORITHM_HMAC_SHA2_384: - case AUTH_ALGORITHM_HMAC_SHA2_512: - case AUTH_ALGORITHM_HMAC_RIPEMD: - auth = sadb_aalg; - break; - default: - /* loose ... */ - auth = sadb_aalg; - } - return auth; -} - -/* - * Search enum_name array with in prefixed uppercase - */ -static int -enum_search_prefix (enum_names *ed, const char *prefix, const char *str, int strlen) -{ - char buf[64]; - char *ptr; - int ret; - int len = sizeof(buf) - 1; /* reserve space for final \0 */ - - for (ptr = buf; *prefix; *ptr++ = *prefix++, len--); - while (strlen-- && len-- && *str) *ptr++ = toupper(*str++); - *ptr = 0; - - DBG(DBG_CRYPT, - DBG_log("enum_search_prefix () calling enum_search(%p, \"%s\")" - , ed, buf) - ) - ret = enum_search(ed, buf); - return ret; -} - -/* - * Search enum_name array with in prefixed and postfixed uppercase - */ -static int -enum_search_ppfix (enum_names *ed, const char *prefix, const char *postfix, const char *str, int strlen) -{ - char buf[64]; - char *ptr; - int ret; - int len = sizeof(buf) - 1; /* reserve space for final \0 */ - - for (ptr = buf; *prefix; *ptr++ = *prefix++, len--); - while (strlen-- && len-- && *str) *ptr++ = toupper(*str++); - while (len-- && *postfix) *ptr++ = *postfix++; - *ptr = 0; - - DBG(DBG_CRYPT, - DBG_log("enum_search_ppfixi () calling enum_search(%p, \"%s\")" - , ed, buf) - ) - ret = enum_search(ed, buf); - return ret; -} - -/* - * Search esp_transformid_names for a match, eg: - * "3des" <=> "ESP_3DES" - */ -#define ESP_MAGIC_ID 0x00ffff01 - -static int -ealg_getbyname_esp(const char *const str, int len) +int alg_info_esp_aa2sadb(int auth) { - if (!str || !*str) - return -1; - - /* leave special case for eg: "id248" string */ - if (strcmp("id", str) == 0) - return ESP_MAGIC_ID; - - return enum_search_prefix(&esp_transformid_names, "ESP_", str, len); + int sadb_aalg = 0; + + switch(auth) { + case AUTH_ALGORITHM_HMAC_MD5: + case AUTH_ALGORITHM_HMAC_SHA1: + sadb_aalg = auth + 1; + break; + case AUTH_ALGORITHM_HMAC_SHA2_256: + case AUTH_ALGORITHM_HMAC_SHA2_384: + case AUTH_ALGORITHM_HMAC_SHA2_512: + case AUTH_ALGORITHM_HMAC_RIPEMD: + sadb_aalg = auth; + break; + default: + /* loose ... */ + sadb_aalg = auth; + } + return sadb_aalg; } -/* - * Search auth_alg_names for a match, eg: - * "md5" <=> "AUTH_ALGORITHM_HMAC_MD5" - */ -static int -aalg_getbyname_esp(const char *const str, int len) +int alg_info_esp_sadb2aa(int sadb_aalg) { - int ret; - unsigned num; - - if (!str || !*str) - return -1; - - /* interpret 'SHA' as 'SHA1' */ - if (strncasecmp("SHA", str, len) == 0) - return AUTH_ALGORITHM_HMAC_SHA1; - - /* interpret 'AESXCBC' as 'AES_XCBC_MAC' */ - if (strncasecmp("AESXCBC", str, len) == 0) - return AUTH_ALGORITHM_AES_XCBC_MAC; - - ret = enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_HMAC_", str ,len); - if (ret >= 0) - return ret; - - ret = enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_", str, len); - if (ret >= 0) - return ret; - - sscanf(str, "id%d%n", &ret, &num); - return (ret >= 0 && num != strlen(str))? -1 : ret; + int auth = 0; + + switch(sadb_aalg) { + case SADB_AALG_MD5HMAC: + case SADB_AALG_SHA1HMAC: + auth = sadb_aalg - 1; + break; + /* since they are the same ... :) */ + case AUTH_ALGORITHM_HMAC_SHA2_256: + case AUTH_ALGORITHM_HMAC_SHA2_384: + case AUTH_ALGORITHM_HMAC_SHA2_512: + case AUTH_ALGORITHM_HMAC_RIPEMD: + auth = sadb_aalg; + break; + default: + /* loose ... */ + auth = sadb_aalg; + } + return auth; } -static int -modp_getbyname_esp(const char *const str, int len) +void alg_info_free(struct alg_info *alg_info) { - int ret; - - if (!str || !*str) - return -1; - - ret = enum_search_prefix(&oakley_group_names,"OAKLEY_GROUP_", str, len); - if (ret >= 0) - return ret; - - ret = enum_search_ppfix(&oakley_group_names, "OAKLEY_GROUP_", " (extension)", str, len); - return ret; -} - -void -alg_info_free(struct alg_info *alg_info) -{ - pfreeany(alg_info); + free(alg_info); } /* * Raw add routine: only checks for no duplicates */ -static void -__alg_info_esp_add (struct alg_info_esp *alg_info, int ealg_id, unsigned ek_bits, int aalg_id, unsigned ak_bits) +static void __alg_info_esp_add(struct alg_info_esp *alg_info, int ealg_id, + unsigned ek_bits, int aalg_id, unsigned ak_bits) { - struct esp_info *esp_info=alg_info->esp; - unsigned cnt = alg_info->alg_info_cnt, i; + struct esp_info *esp_info = alg_info->esp; + unsigned cnt = alg_info->alg_info_cnt, i; - /* check for overflows */ - passert(cnt < elemsof(alg_info->esp)); + /* check for overflows */ + passert(cnt < countof(alg_info->esp)); - /* dont add duplicates */ - for (i = 0; i < cnt; i++) - { - if (esp_info[i].esp_ealg_id == ealg_id - && (!ek_bits || esp_info[i].esp_ealg_keylen == ek_bits) - && esp_info[i].esp_aalg_id == aalg_id - && (!ak_bits || esp_info[i].esp_aalg_keylen == ak_bits)) - return; - } + /* dont add duplicates */ + for (i = 0; i < cnt; i++) + { + if (esp_info[i].esp_ealg_id == ealg_id + && (!ek_bits || esp_info[i].esp_ealg_keylen == ek_bits) + && esp_info[i].esp_aalg_id == aalg_id + && (!ak_bits || esp_info[i].esp_aalg_keylen == ak_bits)) + { + return; + } + } - esp_info[cnt].esp_ealg_id = ealg_id; - esp_info[cnt].esp_ealg_keylen = ek_bits; - esp_info[cnt].esp_aalg_id = aalg_id; - esp_info[cnt].esp_aalg_keylen = ak_bits; + esp_info[cnt].esp_ealg_id = ealg_id; + esp_info[cnt].esp_ealg_keylen = ek_bits; + esp_info[cnt].esp_aalg_id = aalg_id; + esp_info[cnt].esp_aalg_keylen = ak_bits; - /* sadb values */ - esp_info[cnt].encryptalg = ealg_id; - esp_info[cnt].authalg = alg_info_esp_aa2sadb(aalg_id); - alg_info->alg_info_cnt++; + /* sadb values */ + esp_info[cnt].encryptalg = ealg_id; + esp_info[cnt].authalg = alg_info_esp_aa2sadb(aalg_id); + alg_info->alg_info_cnt++; - DBG(DBG_CRYPT, - DBG_log("__alg_info_esp_add() ealg=%d aalg=%d cnt=%d" - , ealg_id, aalg_id, alg_info->alg_info_cnt) - ) + DBG(DBG_CRYPT, + DBG_log("esp alg added: %s_%d/%s, cnt=%d", + enum_show(&esp_transformid_names, ealg_id), ek_bits, + enum_show(&auth_alg_names, aalg_id), + alg_info->alg_info_cnt) + ) } /* * Add ESP alg info _with_ logic (policy): */ -static void -alg_info_esp_add (struct alg_info *alg_info, int ealg_id, int ek_bits, int aalg_id, int ak_bits) +static void alg_info_esp_add(struct alg_info *alg_info, int ealg_id, + int ek_bits, int aalg_id, int ak_bits) { - /* Policy: default to 3DES */ - if (ealg_id == 0) - ealg_id = ESP_3DES; - - if (ealg_id > 0) - { -#ifndef NO_PLUTO - if (aalg_id > 0) -#else - /* Allow no auth for manual conns (from spi.c) */ - if (aalg_id >= 0) -#endif - __alg_info_esp_add((struct alg_info_esp *)alg_info, - ealg_id, ek_bits, - aalg_id, ak_bits); - else + /* Policy: default to 3DES */ + if (ealg_id == 0) { - /* Policy: default to MD5 and SHA1 */ - __alg_info_esp_add((struct alg_info_esp *)alg_info, - ealg_id, ek_bits, - AUTH_ALGORITHM_HMAC_MD5, ak_bits); - __alg_info_esp_add((struct alg_info_esp *)alg_info, - ealg_id, ek_bits, - AUTH_ALGORITHM_HMAC_SHA1, ak_bits); + ealg_id = ESP_3DES; + } + if (ealg_id > 0) + { + if (aalg_id > 0) + { + __alg_info_esp_add((struct alg_info_esp *)alg_info, + ealg_id, ek_bits, + aalg_id, ak_bits); + } + else + { + /* Policy: default to MD5 and SHA1 */ + __alg_info_esp_add((struct alg_info_esp *)alg_info, + ealg_id, ek_bits, + AUTH_ALGORITHM_HMAC_MD5, ak_bits); + __alg_info_esp_add((struct alg_info_esp *)alg_info, + ealg_id, ek_bits, + AUTH_ALGORITHM_HMAC_SHA1, ak_bits); + } } - } -} - -#ifndef NO_PLUTO -/************************************** - * - * IKE alg - * - *************************************/ -/* - * Search oakley_enc_names for a match, eg: - * "3des_cbc" <=> "OAKLEY_3DES_CBC" - */ -static int -ealg_getbyname_ike(const char *const str, int len) -{ - int ret; - - if (!str || !*str) - return -1; - - ret = enum_search_prefix(&oakley_enc_names,"OAKLEY_", str, len); - if (ret >= 0) - return ret; - - ret = enum_search_ppfix(&oakley_enc_names, "OAKLEY_", "_CBC", str, len); - return ret; -} - -/* - * Search oakley_hash_names for a match, eg: - * "md5" <=> "OAKLEY_MD5" - */ -static int -aalg_getbyname_ike(const char *const str, int len) -{ - int ret; - unsigned num; - - if (!str || !*str) - return -1; - - /* interpret 'SHA1' as 'SHA' */ - if (strncasecmp("SHA1", str, len) == 0) - return enum_search(&oakley_hash_names, "OAKLEY_SHA"); - - ret = enum_search_prefix(&oakley_hash_names,"OAKLEY_", str, len); - if (ret >= 0) - return ret; - - sscanf(str, "id%d%n", &ret, &num); - return (ret >=0 && num != strlen(str))? -1 : ret; -} - -/* - * Search oakley_group_names for a match, eg: - * "modp1024" <=> "OAKLEY_GROUP_MODP1024" - */ -static int -modp_getbyname_ike(const char *const str, int len) -{ - int ret; - - if (!str || !*str) - return -1; - - ret = enum_search_prefix(&oakley_group_names,"OAKLEY_GROUP_", str, len); - if (ret >= 0) - return ret; - - ret = enum_search_ppfix(&oakley_group_names, "OAKLEY_GROUP_", " (extension)", str, len); - return ret; } -static void -__alg_info_ike_add (struct alg_info_ike *alg_info, int ealg_id, unsigned ek_bits, int aalg_id, unsigned ak_bits, int modp_id) +static void __alg_info_ike_add (struct alg_info_ike *alg_info, int ealg_id, + unsigned ek_bits, int aalg_id, unsigned ak_bits, + int modp_id) { - struct ike_info *ike_info = alg_info->ike; - unsigned cnt = alg_info->alg_info_cnt; - unsigned i; + struct ike_info *ike_info = alg_info->ike; + unsigned cnt = alg_info->alg_info_cnt; + unsigned i; - /* check for overflows */ - passert(cnt < elemsof(alg_info->ike)); + /* check for overflows */ + passert(cnt < countof(alg_info->ike)); - /* dont add duplicates */ - for (i = 0;i < cnt; i++) + /* dont add duplicates */ + for (i = 0; i < cnt; i++) { - if (ike_info[i].ike_ealg == ealg_id - && (!ek_bits || ike_info[i].ike_eklen == ek_bits) - && ike_info[i].ike_halg == aalg_id - && (!ak_bits || ike_info[i].ike_hklen == ak_bits) - && ike_info[i].ike_modp==modp_id) - return; - } + if (ike_info[i].ike_ealg == ealg_id + && (!ek_bits || ike_info[i].ike_eklen == ek_bits) + && ike_info[i].ike_halg == aalg_id + && (!ak_bits || ike_info[i].ike_hklen == ak_bits) + && ike_info[i].ike_modp==modp_id) + return; + } - ike_info[cnt].ike_ealg = ealg_id; - ike_info[cnt].ike_eklen = ek_bits; - ike_info[cnt].ike_halg = aalg_id; - ike_info[cnt].ike_hklen = ak_bits; - ike_info[cnt].ike_modp = modp_id; - alg_info->alg_info_cnt++; + ike_info[cnt].ike_ealg = ealg_id; + ike_info[cnt].ike_eklen = ek_bits; + ike_info[cnt].ike_halg = aalg_id; + ike_info[cnt].ike_hklen = ak_bits; + ike_info[cnt].ike_modp = modp_id; + alg_info->alg_info_cnt++; - DBG(DBG_CRYPT, - DBG_log("__alg_info_ike_add() ealg=%d aalg=%d modp_id=%d, cnt=%d" - , ealg_id, aalg_id, modp_id - , alg_info->alg_info_cnt) - ) + DBG(DBG_CRYPT, + DBG_log("ikg alg added: %s_%d/%s/%s, cnt=%d", + enum_show(&oakley_enc_names, ealg_id), ek_bits, + enum_show(&oakley_hash_names, aalg_id), + enum_show(&oakley_group_names, modp_id), + alg_info->alg_info_cnt) + ) } /* @@ -419,792 +215,449 @@ __alg_info_ike_add (struct alg_info_ike *alg_info, int ealg_id, unsigned ek_bits */ static int default_ike_groups[] = { - OAKLEY_GROUP_MODP1536, - OAKLEY_GROUP_MODP1024 + MODP_1536_BIT, + MODP_1024_BIT }; -/* - * Add IKE alg info _with_ logic (policy): +/* + * Add IKE alg info _with_ logic (policy): */ -static void -alg_info_ike_add (struct alg_info *alg_info, int ealg_id, int ek_bits, int aalg_id, int ak_bits, int modp_id) +static void alg_info_ike_add (struct alg_info *alg_info, int ealg_id, + int ek_bits, int aalg_id, int ak_bits, int modp_id) { - int i = 0; - int n_groups = elemsof(default_ike_groups); - - /* if specified modp_id avoid loop over default_ike_groups */ - if (modp_id) - { - n_groups=0; - goto in_loop; - } - - for (; n_groups--; i++) - { - modp_id = default_ike_groups[i]; -in_loop: - /* Policy: default to 3DES */ - if (ealg_id == 0) - ealg_id = OAKLEY_3DES_CBC; + int i = 0; + int n_groups = countof(default_ike_groups); - if (ealg_id > 0) + /* if specified modp_id avoid loop over default_ike_groups */ + if (modp_id) { - if (aalg_id > 0) - __alg_info_ike_add((struct alg_info_ike *)alg_info, - ealg_id, ek_bits, - aalg_id, ak_bits, - modp_id); - else - { - /* Policy: default to MD5 and SHA */ - __alg_info_ike_add((struct alg_info_ike *)alg_info, - ealg_id, ek_bits, - OAKLEY_MD5, ak_bits, - modp_id); - __alg_info_ike_add((struct alg_info_ike *)alg_info, - ealg_id, ek_bits, - OAKLEY_SHA, ak_bits, - modp_id); - } + n_groups=0; + goto in_loop; + } + + for (; n_groups--; i++) + { + modp_id = default_ike_groups[i]; +in_loop: + /* Policy: default to 3DES */ + if (ealg_id == 0) + { + ealg_id = OAKLEY_3DES_CBC; + } + if (ealg_id > 0) + { + if (aalg_id > 0) + { + __alg_info_ike_add((struct alg_info_ike *)alg_info, + ealg_id, ek_bits, + aalg_id, ak_bits, + modp_id); + } + else + { + /* Policy: default to MD5 and SHA */ + __alg_info_ike_add((struct alg_info_ike *)alg_info, + ealg_id, ek_bits, + OAKLEY_MD5, ak_bits, + modp_id); + __alg_info_ike_add((struct alg_info_ike *)alg_info, + ealg_id, ek_bits, + OAKLEY_SHA, ak_bits, + modp_id); + } + } } - } -} -#endif /* NO_PLUTO */ - -/* - * Creates a new alg_info by parsing passed string - */ -enum parser_state_esp { - ST_INI, - ST_EA, /* encrypt algo */ - ST_EA_END, - ST_EK, /* enc. key length */ - ST_EK_END, - ST_AA, /* auth algo */ - ST_AA_END, - ST_AK, /* auth. key length */ - ST_AK_END, - ST_MODP, /* modp spec */ - ST_FLAG_STRICT, - ST_END, - ST_EOF, - ST_ERR -}; - -static const char *parser_state_esp_names[] = { - "ST_INI", - "ST_EA", - "ST_EA_END", - "ST_EK", - "ST_EK_END", - "ST_AA", - "ST_AA_END", - "ST_AK", - "ST_AK_END", - "ST_MOPD", - "ST_FLAG_STRICT", - "ST_END", - "ST_EOF", - "ST_ERR" -}; - -static const char* -parser_state_name_esp(enum parser_state_esp state) -{ - return parser_state_esp_names[state]; -} - -/* XXX:jjo to implement different parser for ESP and IKE */ -struct parser_context { - unsigned state, old_state; - unsigned protoid; - char ealg_buf[16]; - char aalg_buf[16]; - char modp_buf[16]; - int (*ealg_getbyname)(const char *const str, int len); - int (*aalg_getbyname)(const char *const str, int len); - int (*modp_getbyname)(const char *const str, int len); - char *ealg_str; - char *aalg_str; - char *modp_str; - int eklen; - int aklen; - int ch; - const char *err; -}; - -static inline void -parser_set_state(struct parser_context *p_ctx, enum parser_state_esp state) -{ - if (state != p_ctx->state) - { - p_ctx->old_state = p_ctx->state; - p_ctx->state = state; - } } -static int -parser_machine(struct parser_context *p_ctx) +static status_t alg_info_add(chunk_t alg, unsigned protoid, + int *ealg, size_t *ealg_keysize, + int *aalg, size_t *aalg_keysize, int *dh_group) { - int ch = p_ctx->ch; - - /* special 'absolute' cases */ - p_ctx->err = "No error."; + const proposal_token_t *token = proposal_get_token(alg.ptr, alg.len); - /* chars that end algo strings */ - switch (ch){ - case 0: /* end-of-string */ - case '!': /* flag as strict algo list */ - case ',': /* algo string separator */ - switch (p_ctx->state) { - case ST_EA: - case ST_EK: - case ST_AA: - case ST_AK: - case ST_MODP: - case ST_FLAG_STRICT: - { - enum parser_state_esp next_state = 0; - - switch (ch) { - case 0: - next_state = ST_EOF; - break; - case ',': - next_state = ST_END; - break; - case '!': - next_state = ST_FLAG_STRICT; - break; - } - /* ch? parser_set_state(p_ctx, ST_END) : parser_set_state(p_ctx, ST_EOF) ; */ - parser_set_state(p_ctx, next_state); - goto out; - } - default: - p_ctx->err = "String ended with invalid char"; - goto err; - } - } -re_eval: - switch (p_ctx->state) { - case ST_INI: - if (isspace(ch)) - break; - if (isalnum(ch)) - { - *(p_ctx->ealg_str++) = ch; - parser_set_state(p_ctx, ST_EA); - break; - } - p_ctx->err = "No alphanum. char initially found"; - goto err; - case ST_EA: - if (isalpha(ch) || ch == '_') - { - *(p_ctx->ealg_str++) = ch; - break; - } - if (isdigit(ch)) - { - /* bravely switch to enc keylen */ - *(p_ctx->ealg_str) = 0; - parser_set_state(p_ctx, ST_EK); - goto re_eval; - } - if (ch == '-') - { - *(p_ctx->ealg_str) = 0; - parser_set_state(p_ctx, ST_EA_END); - break; - } - p_ctx->err = "No valid char found after enc alg string"; - goto err; - case ST_EA_END: - if (isdigit(ch)) - { - /* bravely switch to enc keylen */ - parser_set_state(p_ctx, ST_EK); - goto re_eval; - } - if (isalpha(ch)) - { - parser_set_state(p_ctx, ST_AA); - goto re_eval; - } - p_ctx->err = "No alphanum char found after enc alg separator"; - goto err; - case ST_EK: - if (ch == '-') - { - parser_set_state(p_ctx, ST_EK_END); - break; - } - if (isdigit(ch)) - { - p_ctx->eklen = p_ctx->eklen*10 + ch - '0'; - break; - } - p_ctx->err = "Non digit or valid separator found while reading enc keylen"; - goto err; - case ST_EK_END: - if (isalpha(ch)) - { - parser_set_state(p_ctx, ST_AA); - goto re_eval; - } - p_ctx->err = "Non alpha char found after enc keylen end separator"; - goto err; - case ST_AA: - if (ch == '-') - { - *(p_ctx->aalg_str++) = 0; - parser_set_state(p_ctx, ST_AA_END); - break; - } - if (isalnum(ch) || ch == '_') - { - *(p_ctx->aalg_str++) = ch; - break; - } - p_ctx->err = "Non alphanum or valid separator found in auth string"; - goto err; - case ST_AA_END: - if (isdigit(ch)) - { - parser_set_state(p_ctx, ST_AK); - goto re_eval; - } - /* Only allow modpXXXX string if we have a modp_getbyname method */ - if ((p_ctx->modp_getbyname) && isalpha(ch)) - { - parser_set_state(p_ctx, ST_MODP); - goto re_eval; - } - p_ctx->err = "Non initial digit found for auth keylen"; - goto err; - case ST_AK: - if (ch=='-') - { - parser_set_state(p_ctx, ST_AK_END); - break; - } - if (isdigit(ch)) + if (token == NULL) { - p_ctx->aklen = p_ctx->aklen*10 + ch - '0'; - break; + return FAILED; } - p_ctx->err = "Non digit found for auth keylen"; - goto err; - case ST_AK_END: - /* Only allow modpXXXX string if we have a modp_getbyname method */ - if ((p_ctx->modp_getbyname) && isalpha(ch)) + switch (token->type) { - parser_set_state(p_ctx, ST_MODP); - goto re_eval; - } - p_ctx->err = "Non alpha char found after auth keylen"; - goto err; - case ST_MODP: - if (isalnum(ch)) - { - *(p_ctx->modp_str++) = ch; - break; - } - p_ctx->err = "Non alphanum char found after in modp string"; - goto err; - case ST_FLAG_STRICT: - if (ch == 0) - parser_set_state(p_ctx, ST_END); - p_ctx->err = "Flags character(s) must be at end of whole string"; - goto err; - - /* XXX */ - case ST_END: - case ST_EOF: - case ST_ERR: - break; - /* XXX */ - } -out: - return p_ctx->state; -err: - parser_set_state(p_ctx, ST_ERR); - return ST_ERR; + case ENCRYPTION_ALGORITHM: + if (*ealg != 0) + { + return FAILED; + } + *ealg = (protoid == PROTO_ISAKMP) ? + oakley_from_encryption_algorithm(token->algorithm) : + esp_from_encryption_algorithm(token->algorithm); + if (*ealg == 0) + { + return FAILED; + } + *ealg_keysize = token->keysize; + break; + case INTEGRITY_ALGORITHM: + if (*aalg != 0) + { + return FAILED; + } + *aalg = (protoid == PROTO_ISAKMP) ? + oakley_from_integrity_algorithm(token->algorithm) : + esp_from_integrity_algorithm(token->algorithm); + if (*aalg == 0) + { + return FAILED; + } + *aalg_keysize = token->keysize; + break; + case DIFFIE_HELLMAN_GROUP: + if (protoid == PROTO_ISAKMP) + { + if (*dh_group != 0) + { + return FAILED; + } + *dh_group = token->algorithm; + } + break; + default: + return FAILED; + } + return SUCCESS; } -/* - * Must be called for each "new" char, with new - * character in ctx.ch - */ -static void -parser_init(struct parser_context *p_ctx, unsigned protoid) -{ - memset(p_ctx, 0, sizeof (*p_ctx)); - p_ctx->protoid = protoid; /* XXX: jjo */ - p_ctx->protoid = PROTO_IPSEC_ESP; - p_ctx->ealg_str = p_ctx->ealg_buf; - p_ctx->aalg_str = p_ctx->aalg_buf; - p_ctx->modp_str = p_ctx->modp_buf; - p_ctx->state = ST_INI; - - switch (protoid) { -#ifndef NO_PLUTO - case PROTO_ISAKMP: - p_ctx->ealg_getbyname = ealg_getbyname_ike; - p_ctx->aalg_getbyname = aalg_getbyname_ike; - p_ctx->modp_getbyname = modp_getbyname_ike; - break; -#endif - case PROTO_IPSEC_ESP: - p_ctx->ealg_getbyname = ealg_getbyname_esp; - p_ctx->aalg_getbyname = aalg_getbyname_esp; - break; - } -} -static int -parser_alg_info_add(struct parser_context *p_ctx, struct alg_info *alg_info) +static status_t alg_info_parse_str(struct alg_info *alg_info, char *alg_str) { - int ealg_id = 0; - int aalg_id = 0; - int modp_id = 0; -#ifndef NO_PLUTO - const struct oakley_group_desc *gd; -#endif + char *strict, *single; + status_t status = SUCCESS; - if (*p_ctx->ealg_buf) - { - ealg_id = p_ctx->ealg_getbyname(p_ctx->ealg_buf, strlen(p_ctx->ealg_buf)); - if (ealg_id == ESP_MAGIC_ID) - { - ealg_id = p_ctx->eklen; - p_ctx->eklen = 0; - } - if (ealg_id < 0) + strict = alg_str + strlen(alg_str) - 1; + if (*strict == '!') { - p_ctx->err = "enc_alg not found"; - return -1; + alg_info->alg_info_flags |= ALG_INFO_F_STRICT; + *strict = '\0'; } - DBG(DBG_CRYPT, - DBG_log("parser_alg_info_add() ealg_getbyname(\"%s\")=%d" - , p_ctx->ealg_buf - , ealg_id) - ) - } - if (*p_ctx->aalg_buf) - { - aalg_id = p_ctx->aalg_getbyname(p_ctx->aalg_buf, strlen(p_ctx->aalg_buf)); - if (aalg_id < 0) + while ((single = strsep(&alg_str, ","))) { - p_ctx->err = "hash_alg not found"; - return -1; - } - DBG(DBG_CRYPT, - DBG_log("parser_alg_info_add() aalg_getbyname(\"%s\")=%d" - , p_ctx->aalg_buf - , aalg_id) - ) - } - if (p_ctx->modp_getbyname && *p_ctx->modp_buf) - { - modp_id = p_ctx->modp_getbyname(p_ctx->modp_buf, strlen(p_ctx->modp_buf)); - if (modp_id < 0) - { - p_ctx->err = "modp group not found"; - return -1; - } - DBG(DBG_CRYPT, - DBG_log("parser_alg_info_add() modp_getbyname(\"%s\")=%d" - , p_ctx->modp_buf - , modp_id) - ) - } - switch (alg_info->alg_info_protoid) { - case PROTO_IPSEC_ESP: - alg_info_esp_add(alg_info, - ealg_id, p_ctx->eklen, - aalg_id, p_ctx->aklen); - break; -#ifndef NO_PLUTO - case PROTO_ISAKMP: - if (modp_id && !(gd = lookup_group(modp_id))) - { - p_ctx->err = "found modp group id, but not supported"; - return -1; - } - alg_info_ike_add(alg_info, - ealg_id, p_ctx->eklen, - aalg_id, p_ctx->aklen, - modp_id); - break; -#endif - default: - return -1; - } - return 0; -} + chunk_t string = { (u_char *)single, strlen(single) }; + int ealg = 0; + int aalg = 0; + int dh_group = 0; + size_t ealg_keysize = 0; + size_t aalg_keysize = 0; -static int -alg_info_parse_str (struct alg_info *alg_info, const char *alg_str, const char **err_p) -{ - struct parser_context ctx; - int ret; - const char *ptr; - static char err_buf[256]; - - *err_buf = 0; - parser_init(&ctx, alg_info->alg_info_protoid); - if (err_p) - *err_p = NULL; + eat_whitespace(&string); - /* use default if nul esp string */ - if (!*alg_str) - { - switch (alg_info->alg_info_protoid) { -#ifndef NO_PLUTO - case PROTO_ISAKMP: - alg_info_ike_add(alg_info, 0, 0, 0, 0, 0); - return 0; -#endif - case PROTO_IPSEC_ESP: - alg_info_esp_add(alg_info, 0, 0, 0, 0); - return 0; - default: - /* IMPOSSIBLE */ - passert(alg_info->alg_info_protoid); - } - } + if (string.len > 0) + { + chunk_t alg; + + /* get all token, separated by '-' */ + while (extract_token(&alg, '-', &string)) + { + status |= alg_info_add(alg, alg_info->alg_info_protoid, + &ealg, &ealg_keysize, + &aalg, &aalg_keysize, &dh_group); + } + if (string.len) + { + status |= alg_info_add(string, alg_info->alg_info_protoid, + &ealg, &ealg_keysize, + &aalg, &aalg_keysize, &dh_group); + } + } + if (status == SUCCESS) - for (ret = 0, ptr = alg_str; ret < ST_EOF;) - { - ctx.ch = *ptr++; - ret = parser_machine(&ctx); - - switch (ret) { - case ST_FLAG_STRICT: - alg_info->alg_info_flags |= ALG_INFO_F_STRICT; - break; - case ST_END: - case ST_EOF: - DBG(DBG_CRYPT, - DBG_log("alg_info_parse_str() ealg_buf=%s aalg_buf=%s" - "eklen=%d aklen=%d", - ctx.ealg_buf, ctx.aalg_buf, - ctx.eklen, ctx.aklen) - ) - if (parser_alg_info_add(&ctx, alg_info) < 0) - { - snprintf(err_buf, sizeof(err_buf), - "%s, enc_alg=\"%s\", auth_alg=\"%s\", modp=\"%s\"", - ctx.err, - ctx.ealg_buf, - ctx.aalg_buf, - ctx.modp_buf); - goto err; - } - /* zero out for next run (ST_END) */ - parser_init(&ctx, alg_info->alg_info_protoid); - break; - case ST_ERR: - snprintf(err_buf, sizeof(err_buf), - "%s, just after \"%.*s\" (old_state=%s)", - ctx.err, - (int)(ptr-alg_str-1), alg_str , - parser_state_name_esp(ctx.old_state)); - goto err; - default: - if (!ctx.ch) - break; + { + switch (alg_info->alg_info_protoid) + { + case PROTO_IPSEC_ESP: + alg_info_esp_add(alg_info, ealg, ealg_keysize, + aalg, aalg_keysize); + break; + case PROTO_ISAKMP: + alg_info_ike_add(alg_info, ealg, ealg_keysize, + aalg, aalg_keysize, + dh_group); + break; + default: + break; + } + } } - } - return 0; -err: - if (err_p) - *err_p=err_buf; - return -1; + return status; } -struct alg_info_esp * -alg_info_esp_create_from_str (const char *alg_str, const char **err_p) +struct alg_info_esp *alg_info_esp_create_from_str(char *alg_str) { - struct alg_info_esp *alg_info_esp; - char esp_buf[256]; - static char err_buf[256]; - char *pfs_name; - int ret = 0; - /* - * alg_info storage should be sized dynamically - * but this may require 2passes to know - * transform count in advance. - */ - alg_info_esp = alloc_thing (struct alg_info_esp, "alg_info_esp"); - if (!alg_info_esp) - goto out; - - pfs_name=index (alg_str, ';'); - if (pfs_name) - { - memcpy(esp_buf, alg_str, pfs_name-alg_str); - esp_buf[pfs_name-alg_str] = 0; - alg_str = esp_buf; - pfs_name++; - - /* if pfs strings AND first char is not '0' */ - if (*pfs_name && pfs_name[0] != '0') + struct alg_info_esp *alg_info_esp; + char esp_buf[BUF_LEN]; + char *pfs_name; + status_t status = SUCCESS; + /* + * alg_info storage should be sized dynamically + * but this may require 2passes to know + * transform count in advance. + */ + alg_info_esp = malloc_thing (struct alg_info_esp); + zero(alg_info_esp); + + pfs_name=index (alg_str, ';'); + if (pfs_name) { - ret = modp_getbyname_esp(pfs_name, strlen(pfs_name)); - if (ret < 0) - { - /* Bomb if pfsgroup not found */ - DBG(DBG_CRYPT, - DBG_log("alg_info_esp_create_from_str(): pfsgroup \"%s\" not found" - , pfs_name) - ) - if (*err_p) - { - snprintf(err_buf, sizeof(err_buf), - "pfsgroup \"%s\" not found", - pfs_name); + memcpy(esp_buf, alg_str, pfs_name-alg_str); + esp_buf[pfs_name-alg_str] = 0; + alg_str = esp_buf; + pfs_name++; - *err_p = err_buf; + /* if pfs strings AND first char is not '0' */ + if (*pfs_name && pfs_name[0] != '0') + { + const proposal_token_t *token; + + token = proposal_get_token(pfs_name, strlen(pfs_name)); + if (token == NULL || token->type != DIFFIE_HELLMAN_GROUP) + { + /* Bomb if pfsgroup not found */ + DBG(DBG_CRYPT, + DBG_log("alg_info_esp_create_from_str(): pfsgroup \"%s\" not found" + , pfs_name) + ) + status = FAILED; + goto out; + } + alg_info_esp->esp_pfsgroup = token->algorithm; } - goto out; - } - alg_info_esp->esp_pfsgroup = ret; } - } - else - alg_info_esp->esp_pfsgroup = 0; - - alg_info_esp->alg_info_protoid = PROTO_IPSEC_ESP; - ret = alg_info_parse_str((struct alg_info *)alg_info_esp, alg_str, err_p) ; + else + { + alg_info_esp->esp_pfsgroup = 0; + } + alg_info_esp->alg_info_protoid = PROTO_IPSEC_ESP; + status = alg_info_parse_str((struct alg_info *)alg_info_esp, alg_str); + out: - if (ret < 0) - { - pfreeany(alg_info_esp); - alg_info_esp = NULL; - } - return alg_info_esp; + if (status != SUCCESS) + { + free(alg_info_esp); + alg_info_esp = NULL; + } + return alg_info_esp; } -#ifndef NO_PLUTO -struct alg_info_ike * -alg_info_ike_create_from_str (const char *alg_str, const char **err_p) +struct alg_info_ike *alg_info_ike_create_from_str(char *alg_str) { - struct alg_info_ike *alg_info_ike; - /* - * alg_info storage should be sized dynamically - * but this may require 2passes to know - * transform count in advance. - */ - alg_info_ike = alloc_thing (struct alg_info_ike, "alg_info_ike"); - alg_info_ike->alg_info_protoid = PROTO_ISAKMP; - - if (alg_info_parse_str((struct alg_info *)alg_info_ike, - alg_str, err_p) < 0) - { - pfreeany(alg_info_ike); - return NULL; - } - return alg_info_ike; + struct alg_info_ike *alg_info_ike; + /* + * alg_info storage should be sized dynamically + * but this may require 2passes to know + * transform count in advance. + */ + alg_info_ike = malloc_thing (struct alg_info_ike); + zero(alg_info_ike); + alg_info_ike->alg_info_protoid = PROTO_ISAKMP; + + if (alg_info_parse_str((struct alg_info *)alg_info_ike, alg_str) != SUCCESS) + { + free(alg_info_ike); + return NULL; + } + return alg_info_ike; } -#endif /* - * alg_info struct can be shared by - * several connections instances, - * handle free() with ref_cnts + * alg_info struct can be shared by + * several connections instances, + * handle free() with ref_cnts */ void alg_info_addref(struct alg_info *alg_info) { - if (alg_info != NULL) - { - alg_info->ref_cnt++; - DBG(DBG_CRYPT, - DBG_log("alg_info_addref() alg_info->ref_cnt=%d" - , alg_info->ref_cnt) - ) - } + if (alg_info != NULL) + { + alg_info->ref_cnt++; + } } void alg_info_delref(struct alg_info **alg_info_p) { - struct alg_info *alg_info = *alg_info_p; + struct alg_info *alg_info = *alg_info_p; - if (alg_info != NULL) - { - passert(alg_info->ref_cnt != 0); - alg_info->ref_cnt--; - DBG(DBG_CRYPT, - DBG_log("alg_info_delref() alg_info->ref_cnt=%d" - , alg_info->ref_cnt) - ) - if (alg_info->ref_cnt == 0) + if (alg_info != NULL) { - DBG(DBG_CRYPT, - DBG_log("alg_info_delref() freeing alg_info") - ) - alg_info_free(alg_info); + passert(alg_info->ref_cnt != 0); + alg_info->ref_cnt--; + if (alg_info->ref_cnt == 0) + { + alg_info_free(alg_info); + } + *alg_info_p = NULL; } - *alg_info_p = NULL; - } } /* snprint already parsed transform list (alg_info) */ int alg_info_snprint(char *buf, int buflen, struct alg_info *alg_info) { - char *ptr = buf; - int np = 0; - struct esp_info *esp_info; -#ifndef NO_PLUTO - struct ike_info *ike_info; -#endif - int cnt; - - switch (alg_info->alg_info_protoid) { - case PROTO_IPSEC_ESP: - { - struct alg_info_esp *alg_info_esp = (struct alg_info_esp *)alg_info; + char *ptr = buf; + int np = 0; + struct esp_info *esp_info; + struct ike_info *ike_info; + int cnt; + + switch (alg_info->alg_info_protoid) { + case PROTO_IPSEC_ESP: + { + struct alg_info_esp *alg_info_esp = (struct alg_info_esp *)alg_info; + + ALG_INFO_ESP_FOREACH(alg_info_esp, esp_info, cnt) + { + np = snprintf(ptr, buflen, "%s", + enum_show(&esp_transformid_names, esp_info->esp_ealg_id)); + ptr += np; + buflen -= np; + if (esp_info->esp_ealg_keylen) + { + np = snprintf(ptr, buflen, "_%u", esp_info->esp_ealg_keylen); + ptr += np; + buflen -= np; + } + np = snprintf(ptr, buflen, "/%s, ", + enum_show(&auth_alg_names, esp_info->esp_aalg_id)); + ptr += np; + buflen -= np; + if (buflen < 0) + goto out; + } + if (alg_info_esp->esp_pfsgroup) + { + np = snprintf(ptr, buflen, "; pfsgroup=%s; ", + enum_show(&oakley_group_names, alg_info_esp->esp_pfsgroup)); + ptr += np; + buflen -= np; + if (buflen < 0) + goto out; + } + break; + } - ALG_INFO_ESP_FOREACH(alg_info_esp, esp_info, cnt) - { - np = snprintf(ptr, buflen, "%d_%03d-%d, " - , esp_info->esp_ealg_id - , (int)esp_info->esp_ealg_keylen - , esp_info->esp_aalg_id); - ptr += np; - buflen -= np; - if (buflen < 0) - goto out; - } - if (alg_info_esp->esp_pfsgroup) - { - np = snprintf(ptr, buflen, "; pfsgroup=%d; " - , alg_info_esp->esp_pfsgroup); + case PROTO_ISAKMP: + ALG_INFO_IKE_FOREACH((struct alg_info_ike *)alg_info, ike_info, cnt) + { + np = snprintf(ptr, buflen, "%s", + enum_show(&oakley_enc_names, ike_info->ike_ealg)); + ptr += np; + buflen -= np; + if (ike_info->ike_eklen) + { + np = snprintf(ptr, buflen, "_%u", ike_info->ike_eklen); + ptr += np; + buflen -= np; + } + np = snprintf(ptr, buflen, "/%s/%s, ", + enum_show(&oakley_hash_names, ike_info->ike_halg), + enum_show(&oakley_group_names, ike_info->ike_modp)); + ptr += np; + buflen -= np; + if (buflen < 0) + goto out; + } + break; + default: + np = snprintf(buf, buflen, "INVALID protoid=%d\n" + , alg_info->alg_info_protoid); ptr += np; buflen -= np; - if (buflen < 0) - goto out; - } - break; - } -#ifndef NO_PLUTO - case PROTO_ISAKMP: - ALG_INFO_IKE_FOREACH((struct alg_info_ike *)alg_info, ike_info, cnt) - { - np = snprintf(ptr, buflen, "%d_%03d-%d-%d, " - , ike_info->ike_ealg - , (int)ike_info->ike_eklen - , ike_info->ike_halg - , ike_info->ike_modp); - ptr += np; - buflen -= np; - if (buflen < 0) goto out; - } - break; -#endif - default: - np = snprintf(buf, buflen, "INVALID protoid=%d\n" - , alg_info->alg_info_protoid); - ptr += np; - buflen -= np; - goto out; } np = snprintf(ptr, buflen, "%s" - , alg_info->alg_info_flags & ALG_INFO_F_STRICT? - "strict":""); + , alg_info->alg_info_flags & ALG_INFO_F_STRICT? + "strict":""); ptr += np; buflen -= np; out: - if (buflen < 0) - { - loglog(RC_LOG_SERIOUS - , "buffer space exhausted in alg_info_snprint_ike(), buflen=%d" - , buflen); - } - - return ptr - buf; + if (buflen < 0) + { + loglog(RC_LOG_SERIOUS + , "buffer space exhausted in alg_info_snprint_ike(), buflen=%d" + , buflen); + } + + return ptr - buf; } -#ifndef NO_PLUTO -int -alg_info_snprint_esp(char *buf, int buflen, struct alg_info_esp *alg_info) +int alg_info_snprint_esp(char *buf, int buflen, struct alg_info_esp *alg_info) { - char *ptr = buf; + char *ptr = buf; - int cnt = alg_info->alg_info_cnt; - struct esp_info *esp_info = alg_info->esp; + int cnt = alg_info->alg_info_cnt; + struct esp_info *esp_info = alg_info->esp; - while (cnt--) - { - if (kernel_alg_esp_enc_ok(esp_info->esp_ealg_id, 0, NULL) - && kernel_alg_esp_auth_ok(esp_info->esp_aalg_id, NULL)) + while (cnt--) { - u_int eklen = (esp_info->esp_ealg_keylen) - ? esp_info->esp_ealg_keylen - : kernel_alg_esp_enc_keylen(esp_info->esp_ealg_id) - * BITS_PER_BYTE; - - u_int aklen = esp_info->esp_aalg_keylen - ? esp_info->esp_aalg_keylen - : kernel_alg_esp_auth_keylen(esp_info->esp_aalg_id) - * BITS_PER_BYTE; - - int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d, ", - esp_info->esp_ealg_id, eklen, - esp_info->esp_aalg_id, aklen); - ptr += ret; - buflen -= ret; - if (buflen < 0) - break; + if (kernel_alg_esp_enc_ok(esp_info->esp_ealg_id, 0, NULL) + && kernel_alg_esp_auth_ok(esp_info->esp_aalg_id, NULL)) + { + u_int eklen = (esp_info->esp_ealg_keylen) + ? esp_info->esp_ealg_keylen + : kernel_alg_esp_enc_keylen(esp_info->esp_ealg_id) + * BITS_PER_BYTE; + + u_int aklen = esp_info->esp_aalg_keylen + ? esp_info->esp_aalg_keylen + : kernel_alg_esp_auth_keylen(esp_info->esp_aalg_id) + * BITS_PER_BYTE; + + int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d, ", + esp_info->esp_ealg_id, eklen, + esp_info->esp_aalg_id, aklen); + ptr += ret; + buflen -= ret; + if (buflen < 0) + break; + } + esp_info++; } - esp_info++; - } - return ptr - buf; + return ptr - buf; } -int -alg_info_snprint_ike(char *buf, int buflen, struct alg_info_ike *alg_info) +int alg_info_snprint_ike(char *buf, int buflen, struct alg_info_ike *alg_info) { - char *ptr = buf; - - int cnt = alg_info->alg_info_cnt; - struct ike_info *ike_info = alg_info->ike; + char *ptr = buf; - while (cnt--) - { - struct encrypt_desc *enc_desc = ike_alg_get_encrypter(ike_info->ike_ealg); - struct hash_desc *hash_desc = ike_alg_get_hasher(ike_info->ike_halg); + int cnt = alg_info->alg_info_cnt; + struct ike_info *ike_info = alg_info->ike; - if (enc_desc != NULL && hash_desc != NULL - && lookup_group(ike_info->ike_modp)) + while (cnt--) { + struct encrypt_desc *enc_desc = ike_alg_get_crypter(ike_info->ike_ealg); + struct hash_desc *hash_desc = ike_alg_get_hasher(ike_info->ike_halg); + struct dh_desc *dh_desc = ike_alg_get_dh_group(ike_info->ike_modp); - u_int eklen = (ike_info->ike_eklen) - ? ike_info->ike_eklen - : enc_desc->keydeflen; - - u_int aklen = (ike_info->ike_hklen) - ? ike_info->ike_hklen - : hash_desc->hash_digest_size * BITS_PER_BYTE; + if (enc_desc && hash_desc && dh_desc) + { - int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d-%d, ", - ike_info->ike_ealg, eklen, - ike_info->ike_halg, aklen, - ike_info->ike_modp); - ptr += ret; - buflen -= ret; - if (buflen < 0) - break; + u_int eklen = (ike_info->ike_eklen) + ? ike_info->ike_eklen + : enc_desc->keydeflen; + + u_int aklen = (ike_info->ike_hklen) + ? ike_info->ike_hklen + : hash_desc->hash_digest_size * BITS_PER_BYTE; + + int ret = snprintf(ptr, buflen, "%d_%03d-%d_%03d-%d, ", + ike_info->ike_ealg, eklen, + ike_info->ike_halg, aklen, + ike_info->ike_modp); + ptr += ret; + buflen -= ret; + if (buflen < 0) + break; + } + ike_info++; } - ike_info++; - } - return ptr - buf; + return ptr - buf; } -#endif /* NO_PLUTO */ + |