From b0471fb2720054f6560dc9df23ab64a63f7b14f5 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Tue, 19 May 2009 07:51:48 +0200 Subject: [PATCH] puto uses proposal_get_token() from libstrongswan --- src/libfreeswan/ipsec_policy.h | 2 +- src/pluto/alg_info.c | 820 ++++++--------------------------- src/pluto/alg_info.h | 9 +- src/pluto/connections.c | 14 +- src/pluto/constants.c | 134 +++--- src/pluto/crypto.c | 126 ++++- src/pluto/crypto.h | 5 + src/pluto/ike_alg.c | 6 +- src/pluto/kernel_alg.c | 7 +- 9 files changed, 350 insertions(+), 773 deletions(-) diff --git a/src/libfreeswan/ipsec_policy.h b/src/libfreeswan/ipsec_policy.h index bcaf818ef..0bbdebb61 100644 --- a/src/libfreeswan/ipsec_policy.h +++ b/src/libfreeswan/ipsec_policy.h @@ -91,7 +91,7 @@ enum ipsec_authentication_algo { */ enum ipsec_cipher_algo { - ESP_NONE = 0, + ESP_NONE = 0, ESP_DES_IV64 = 1, ESP_DES = 2, ESP_3DES = 3, diff --git a/src/pluto/alg_info.c b/src/pluto/alg_info.c index bd0c73f2b..a39c3fba0 100644 --- a/src/pluto/alg_info.c +++ b/src/pluto/alg_info.c @@ -28,6 +28,12 @@ #include #include +#include +#include +#include +#include +#include + #include "alg_info.h" #include "constants.h" #include "defs.h" @@ -40,8 +46,7 @@ /* * sadb/ESP aa attrib converters */ -int -alg_info_esp_aa2sadb(int auth) +int alg_info_esp_aa2sadb(int auth) { int sadb_aalg = 0; @@ -63,8 +68,7 @@ alg_info_esp_aa2sadb(int auth) return sadb_aalg; } -int /* __attribute__ ((unused)) */ -alg_info_esp_sadb2aa(int sadb_aalg) +int alg_info_esp_sadb2aa(int sadb_aalg) { int auth = 0; @@ -87,126 +91,7 @@ alg_info_esp_sadb2aa(int 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) -{ - if (!str || !*str) - { - return -1; - } - - /* leave special case for eg: "id248" string */ - if (streq("id", str)) - { - return ESP_MAGIC_ID; - } - return enum_search_prefix(&esp_transformid_names, "ESP_", str, len); -} - -/* - * 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 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; -} - -static int -modp_getbyname_esp(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; -} - -void -alg_info_free(struct alg_info *alg_info) +void alg_info_free(struct alg_info *alg_info) { free(alg_info); } @@ -214,8 +99,8 @@ alg_info_free(struct alg_info *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; @@ -230,7 +115,9 @@ __alg_info_esp_add (struct alg_info_esp *alg_info, int ealg_id, unsigned ek_bits && (!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; @@ -252,24 +139,22 @@ __alg_info_esp_add (struct alg_info_esp *alg_info, int ealg_id, unsigned ek_bits /* * 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 MD5 and SHA1 */ @@ -283,79 +168,9 @@ alg_info_esp_add (struct alg_info *alg_info, int ealg_id, int ek_bits, int aalg_ } } -#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; @@ -402,8 +217,8 @@ static int default_ike_groups[] = { /* * 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 = countof(default_ike_groups); @@ -421,15 +236,18 @@ alg_info_ike_add (struct alg_info *alg_info, int ealg_id, int ek_bits, int aalg_ 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 */ @@ -445,470 +263,136 @@ in_loop: } } } -#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) +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) { - return parser_state_esp_names[state]; -} + const proposal_token_t *token = proposal_get_token(alg.ptr, alg.len); -/* 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) + if (token == NULL) { - p_ctx->old_state = p_ctx->state; - p_ctx->state = state; + return FAILED; } -} - -static int -parser_machine(struct parser_context *p_ctx) -{ - int ch = p_ctx->ch; - - /* special 'absolute' cases */ - p_ctx->err = "No error."; - - /* 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: + switch (token->type) + { + case ENCRYPTION_ALGORITHM: + if (*ealg != 0) { - 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; + 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; } - /* ch? parser_set_state(p_ctx, ST_END) : parser_set_state(p_ctx, ST_EOF) ; */ - parser_set_state(p_ctx, next_state); - goto out; + if (token->algorithm > OAKLEY_GROUP_MODP8192) + { + return FAILED; + } + *dh_group = token->algorithm; } + break; default: - p_ctx->err = "String ended with invalid char"; - goto err; - } + return FAILED; } -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)) - { - p_ctx->aklen = p_ctx->aklen*10 + ch - '0'; - break; - } - 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)) - { - 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; + 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) + +static status_t alg_info_parse_str(struct alg_info *alg_info, char *alg_str) { - 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; + char *strict, *single; + status_t status = SUCCESS; - 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) -{ - int ealg_id = 0; - int aalg_id = 0; - int modp_id = 0; -#ifndef NO_PLUTO - const struct oakley_group_desc *gd; -#endif - - if (*p_ctx->ealg_buf) + strict = alg_str + strlen(alg_str) - 1; + if (*strict == '!') { - 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) - { - p_ctx->err = "enc_alg not found"; - return -1; - } - DBG(DBG_CRYPT, - DBG_log("parser_alg_info_add() ealg_getbyname(\"%s\")=%d" - , p_ctx->ealg_buf - , ealg_id) - ) + alg_info->alg_info_flags |= ALG_INFO_F_STRICT; + *strict = '\0'; } - if (*p_ctx->aalg_buf) + while ((single = strsep(&alg_str, ","))) { - aalg_id = p_ctx->aalg_getbyname(p_ctx->aalg_buf, strlen(p_ctx->aalg_buf)); - if (aalg_id < 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; + + eat_whitespace(&string); + + if (string.len > 0) { - 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 alg; -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; - - /* 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); - } - } - - 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) + /* get all token, separated by '-' */ + while (extract_token(&alg, '-', &string)) { - 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; + 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) + + { + 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; } - /* 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; } } - 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; + status_t status = SUCCESS; /* * alg_info storage should be sized dynamically * but this may require 2passes to know @@ -928,34 +412,31 @@ alg_info_esp_create_from_str (const char *alg_str, const char **err_p) /* if pfs strings AND first char is not '0' */ if (*pfs_name && pfs_name[0] != '0') { - ret = modp_getbyname_esp(pfs_name, strlen(pfs_name)); - if (ret < 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) ) - if (*err_p) - { - snprintf(err_buf, sizeof(err_buf), - "pfsgroup \"%s\" not found", - pfs_name); - - *err_p = err_buf; - } + status = FAILED; goto out; } - alg_info_esp->esp_pfsgroup = ret; + alg_info_esp->esp_pfsgroup = token->algorithm; } } 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) ; + status = alg_info_parse_str((struct alg_info *)alg_info_esp, alg_str); + out: - if (ret < 0) + if (status != SUCCESS) { free(alg_info_esp); alg_info_esp = NULL; @@ -963,9 +444,7 @@ out: 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; /* @@ -977,14 +456,13 @@ alg_info_ike_create_from_str (const char *alg_str, const char **err_p) 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, err_p) < 0) + 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 @@ -1035,9 +513,7 @@ 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) { @@ -1067,7 +543,7 @@ alg_info_snprint(char *buf, int buflen, struct alg_info *alg_info) } break; } -#ifndef NO_PLUTO + case PROTO_ISAKMP: ALG_INFO_IKE_FOREACH((struct alg_info_ike *)alg_info, ike_info, cnt) { @@ -1082,7 +558,6 @@ alg_info_snprint(char *buf, int buflen, struct alg_info *alg_info) goto out; } break; -#endif default: np = snprintf(buf, buflen, "INVALID protoid=%d\n" , alg_info->alg_info_protoid); @@ -1107,9 +582,7 @@ out: 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; @@ -1144,8 +617,7 @@ alg_info_snprint_esp(char *buf, int buflen, struct alg_info_esp *alg_info) 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; @@ -1182,4 +654,4 @@ alg_info_snprint_ike(char *buf, int buflen, struct alg_info_ike *alg_info) } return ptr - buf; } -#endif /* NO_PLUTO */ + diff --git a/src/pluto/alg_info.h b/src/pluto/alg_info.h index 894445e1c..fcf7efca0 100644 --- a/src/pluto/alg_info.h +++ b/src/pluto/alg_info.h @@ -65,13 +65,10 @@ extern int alg_info_esp_sadb2aa(int sadb_aalg); extern void alg_info_free(struct alg_info *alg_info); extern void alg_info_addref(struct alg_info *alg_info); extern void alg_info_delref(struct alg_info **alg_info); -extern struct alg_info_esp* alg_info_esp_create_from_str(const char *alg_str - , const char **err_p); -extern struct alg_info_ike* alg_info_ike_create_from_str(const char *alg_str - , const char **err_p); +extern struct alg_info_esp* alg_info_esp_create_from_str(char *alg_str); +extern struct alg_info_ike* alg_info_ike_create_from_str(char *alg_str); extern int alg_info_parse(const char *str); -extern int alg_info_snprint(char *buf, int buflen - , struct alg_info *alg_info); +extern int alg_info_snprint(char *buf, int buflen, struct alg_info *alg_info); extern int alg_info_snprint_esp(char *buf, int buflen , struct alg_info_esp *alg_info); extern int alg_info_snprint_ike(char *buf, int buflen diff --git a/src/pluto/connections.c b/src/pluto/connections.c index 07ae79c2f..b7185977f 100644 --- a/src/pluto/connections.c +++ b/src/pluto/connections.c @@ -985,12 +985,10 @@ add_connection(const whack_message_t *wm) if (wm->esp) { - const char *ugh; - DBG(DBG_CONTROL, DBG_log("from whack: got --esp=%s", wm->esp ? wm->esp: "NULL") ) - c->alg_info_esp= alg_info_esp_create_from_str(wm->esp? wm->esp : "", &ugh); + c->alg_info_esp= alg_info_esp_create_from_str(wm->esp? wm->esp : ""); DBG(DBG_CRYPT|DBG_CONTROL, static char buf[256]=""; @@ -1008,19 +1006,16 @@ add_connection(const whack_message_t *wm) } else { - loglog(RC_LOG_SERIOUS - , "esp string error: %s", ugh? ugh : "Unknown"); + loglog(RC_LOG_SERIOUS, "esp string error"); } } if (wm->ike) { - const char *ugh; - DBG(DBG_CONTROL, DBG_log("from whack: got --ike=%s", wm->ike ? wm->ike: "NULL") ) - c->alg_info_ike= alg_info_ike_create_from_str(wm->ike? wm->ike : "", &ugh); + c->alg_info_ike= alg_info_ike_create_from_str(wm->ike? wm->ike : ""); DBG(DBG_CRYPT|DBG_CONTROL, static char buf[256]=""; @@ -1038,8 +1033,7 @@ add_connection(const whack_message_t *wm) } else { - loglog(RC_LOG_SERIOUS - , "ike string error: %s", ugh? ugh : "Unknown"); + loglog(RC_LOG_SERIOUS, "ike string error:"); } } diff --git a/src/pluto/constants.c b/src/pluto/constants.c index d02772507..910842dc6 100644 --- a/src/pluto/constants.c +++ b/src/pluto/constants.c @@ -373,37 +373,33 @@ enum_names ah_transformid_names = /* IPsec ESP transform values */ static const char *const esp_transform_name[] = { - "ESP_DES_IV64", - "ESP_DES", - "ESP_3DES", - "ESP_RC5", - "ESP_IDEA", - "ESP_CAST", - "ESP_BLOWFISH", - "ESP_3IDEA", - "ESP_DES_IV32", - "ESP_RC4", - "ESP_NULL", - "ESP_AES", - "ESP_AES-CTR", - "ESP_AES-CCM_8", - "ESP_AES-CCM_12", - "ESP_AES-CCM_16", - "ESP_UNASSIGNED_17", - "ESP_AES_GCM_8", - "ESP_AES_GCM_12", - "ESP_AES_GCM_16", - "ESP_SEED_CBC", - "ESP_CAMELLIA" + "DES_IV64", + "DES", + "3DES", + "RC5", + "IDEA", + "CAST", + "BLOWFISH", + "3IDEA", + "DES_IV32", + "RC4", + "NULL", + "AES_CBC", + "AES_CTR", + "AES_CCM_8", + "AES_CCM_12", + "AES_CCM_16", + "UNASSIGNED_17", + "AES_GCM_8", + "AES_GCM_12", + "AES_GCM_16", + "SEED_CBC", + "CAMELLIA_CBC" }; -/* - * ipsec drafts suggest "high" ESP ids values for testing, - * assign generic ESP_ID if not officially defined - */ static const char *const esp_transform_name_high[] = { - "ESP_SERPENT", - "ESP_TWOFISH" + "SERPENT_CBC", + "TWOFISH_CBC" }; enum_names esp_transformid_names_high = @@ -668,20 +664,20 @@ enum_names enc_mode_names = /* Auth Algorithm attribute */ static const char *const auth_alg_name[] = { - "AUTH_ALGORITHM_HMAC_MD5", - "AUTH_ALGORITHM_HMAC_SHA1", - "AUTH_ALGORITHM_DES_MAC", - "AUTH_ALGORITHM_KPDK", - "AUTH_ALGORITHM_HMAC_SHA2_256", - "AUTH_ALGORITHM_HMAC_SHA2_384", - "AUTH_ALGORITHM_HMAC_SHA2_512", - "AUTH_ALGORITHM_HMAC_RIPEMD", - "AUTH_ALGORITHM_AES_XCBC_MAC", - "AUTH_ALGORITHM_SIG_RSA" + "HMAC_MD5", + "HMAC_SHA1", + "DES_MAC", + "KPDK", + "HMAC_SHA2_256", + "HMAC_SHA2_384", + "HMAC_SHA2_512", + "HMAC_RIPEMD", + "AES_XCBC_MAC", + "SIG_RSA" }; static const char *const extended_auth_alg_name[] = { - "AUTH_ALGORITHM_NULL" + "NULL" }; enum_names extended_auth_alg_names = @@ -797,14 +793,14 @@ enum_names oakley_prf_names = /* Oakley Encryption Algorithm attribute */ static const char *const oakley_enc_name[] = { - "OAKLEY_DES_CBC", - "OAKLEY_IDEA_CBC", - "OAKLEY_BLOWFISH_CBC", - "OAKLEY_RC5_R16_B64_CBC", - "OAKLEY_3DES_CBC", - "OAKLEY_CAST_CBC", - "OAKLEY_AES_CBC", - "OAKLEY_CAMELLIA_CBC" + "DES_CBC", + "IDEA_CBC", + "BLOWFISH_CBC", + "RC5_R16_B64_CBC", + "3DES_CBC", + "CAST_CBC", + "AES_CBC", + "CAMELLIA_CBC" }; #ifdef NO_EXTRA_IKE @@ -812,15 +808,15 @@ enum_names oakley_enc_names = { OAKLEY_DES_CBC, OAKLEY_CAMELLIA_CBC, oakley_enc_name, NULL }; #else static const char *const oakley_enc_name_draft_aes_cbc_02[] = { - "OAKLEY_MARS_CBC" /* 65001 */, - "OAKLEY_RC6_CBC" /* 65002 */, - "OAKLEY_ID_65003" /* 65003 */, - "OAKLEY_SERPENT_CBC" /* 65004 */, - "OAKLEY_TWOFISH_CBC" /* 65005 */, + "MARS_CBC" /* 65001 */, + "RC6_CBC" /* 65002 */, + "ID_65003" /* 65003 */, + "SERPENT_CBC" /* 65004 */, + "TWOFISH_CBC" /* 65005 */, }; static const char *const oakley_enc_name_ssh[] = { - "OAKLEY_TWOFISH_CBC_SSH", + "TWOFISH_CBC_SSH", }; enum_names oakley_enc_names_ssh = @@ -839,12 +835,12 @@ enum_names oakley_enc_names = /* Oakley Hash Algorithm attribute */ static const char *const oakley_hash_name[] = { - "OAKLEY_MD5", - "OAKLEY_SHA", - "OAKLEY_TIGER", - "OAKLEY_SHA2_256", - "OAKLEY_SHA2_384", - "OAKLEY_SHA2_512", + "HMAC_MD5", + "HMAC_SHA1", + "HMAC_TIGER", + "HMAC_SHA2_256", + "HMAC_SHA2_384", + "HMAC_SHA2_512", }; enum_names oakley_hash_names = @@ -897,19 +893,19 @@ enum_names oakley_auth_names = /* Oakley Group Description attribute */ static const char *const oakley_group_name[] = { - "OAKLEY_GROUP_MODP768", - "OAKLEY_GROUP_MODP1024", - "OAKLEY_GROUP_GP155", - "OAKLEY_GROUP_GP185", - "OAKLEY_GROUP_MODP1536", + "MODP_768", + "MODP_1024", + "GP_155", + "GP_185", + "MODP_1536", }; static const char *const oakley_group_name_rfc3526[] = { - "OAKLEY_GROUP_MODP2048", - "OAKLEY_GROUP_MODP3072", - "OAKLEY_GROUP_MODP4096", - "OAKLEY_GROUP_MODP6144", - "OAKLEY_GROUP_MODP8192" + "MODP_2048", + "MODP_3072", + "MODP_4096", + "MODP_6144", + "MODP_8192" }; enum_names oakley_group_names_rfc3526 = diff --git a/src/pluto/crypto.c b/src/pluto/crypto.c index 7da967c52..2712abe16 100644 --- a/src/pluto/crypto.c +++ b/src/pluto/crypto.c @@ -16,9 +16,7 @@ #include #include - -#include -#include +#include #include "constants.h" #include "defs.h" @@ -266,3 +264,125 @@ pseudo_random_function_t oakley_to_prf(int alg) return PRF_UNDEFINED; } } + +/** + * Converts IKEv2 encryption to IKEv1 encryption algorithm + */ +int oakley_from_encryption_algorithm(encryption_algorithm_t alg) +{ + switch (alg) + { + case ENCR_DES: + return OAKLEY_DES_CBC; + case ENCR_3DES: + return OAKLEY_3DES_CBC; + case ENCR_RC5: + return OAKLEY_RC5_R16_B64_CBC; + case ENCR_IDEA: + return OAKLEY_IDEA_CBC; + case ENCR_CAST: + return OAKLEY_CAST_CBC; + case ENCR_BLOWFISH: + return OAKLEY_BLOWFISH_CBC; + case ENCR_AES_CBC: + return OAKLEY_AES_CBC; + case ENCR_CAMELLIA_CBC: + return OAKLEY_CAMELLIA_CBC; + case ENCR_SERPENT_CBC: + return OAKLEY_SERPENT_CBC; + case ENCR_TWOFISH_CBC: + return OAKLEY_TWOFISH_CBC; + default: + return 0; + } +} + +/** + * Converts IKEv2 integrity to IKEv1 hash algorithm + */ +int oakley_from_integrity_algorithm(integrity_algorithm_t alg) +{ + switch (alg) + { + case AUTH_HMAC_MD5_96: + return OAKLEY_MD5; + case AUTH_HMAC_SHA1_96: + return OAKLEY_SHA; + case AUTH_HMAC_SHA2_256_128: + return OAKLEY_SHA2_256; + case AUTH_HMAC_SHA2_384_192: + return OAKLEY_SHA2_384; + case AUTH_HMAC_SHA2_512_256: + return OAKLEY_SHA2_512; + default: + return 0; + } +} + +/** + * Converts IKEv2 encryption to IKEv1 ESP encryption algorithm + */ +int esp_from_encryption_algorithm(encryption_algorithm_t alg) +{ + switch (alg) + { + case ENCR_DES: + return ESP_DES; + case ENCR_3DES: + return ESP_3DES; + case ENCR_RC5: + return ESP_RC5; + case ENCR_IDEA: + return ESP_IDEA; + case ENCR_CAST: + return ESP_CAST; + case ENCR_BLOWFISH: + return ESP_BLOWFISH; + case ENCR_AES_CBC: + return OAKLEY_AES_CBC; + case ENCR_AES_CTR: + return ESP_AES_CTR; + case ENCR_AES_CCM_ICV8: + return ESP_AES_CCM_8; + case ENCR_AES_CCM_ICV12: + return ESP_AES_CCM_12; + case ENCR_AES_CCM_ICV16: + return ESP_AES_CCM_16; + case ENCR_AES_GCM_ICV8: + return ESP_AES_GCM_8; + case ENCR_AES_GCM_ICV12: + return ESP_AES_GCM_12; + case ENCR_AES_GCM_ICV16: + return ESP_AES_GCM_16; + case ENCR_CAMELLIA_CBC: + return ESP_CAMELLIA; + case ENCR_SERPENT_CBC: + return ESP_SERPENT; + case ENCR_TWOFISH_CBC: + return ESP_TWOFISH; + default: + return 0; + } +} + +/** + * Converts IKEv2 integrity to IKEv1 ESP authentication algorithm + */ +int esp_from_integrity_algorithm(integrity_algorithm_t alg) +{ + switch (alg) + { + case AUTH_HMAC_MD5_96: + return AUTH_ALGORITHM_HMAC_MD5; + case AUTH_HMAC_SHA1_96: + return AUTH_ALGORITHM_HMAC_SHA1; + case AUTH_HMAC_SHA2_256_128: + return AUTH_ALGORITHM_HMAC_SHA2_256; + case AUTH_HMAC_SHA2_384_192: + return AUTH_ALGORITHM_HMAC_SHA2_384; + case AUTH_HMAC_SHA2_512_256: + return AUTH_ALGORITHM_HMAC_SHA2_512; + default: + return 0; + } +} diff --git a/src/pluto/crypto.h b/src/pluto/crypto.h index ae05524d4..0f8741e01 100644 --- a/src/pluto/crypto.h +++ b/src/pluto/crypto.h @@ -13,6 +13,7 @@ */ #include +#include #include #include @@ -60,4 +61,8 @@ struct state; /* forward declaration, dammit */ extern encryption_algorithm_t oakley_to_encryption_algorithm(int alg); extern hash_algorithm_t oakley_to_hash_algorithm(int alg); extern pseudo_random_function_t oakley_to_prf(int alg); +extern int oakley_from_encryption_algorithm(encryption_algorithm_t alg); +extern int oakley_from_integrity_algorithm(integrity_algorithm_t alg); +extern int esp_from_encryption_algorithm(encryption_algorithm_t alg); +extern int esp_from_integrity_algorithm(integrity_algorithm_t alg); diff --git a/src/pluto/ike_alg.c b/src/pluto/ike_alg.c index 3b9cf8464..7922d54b2 100644 --- a/src/pluto/ike_alg.c +++ b/src/pluto/ike_alg.c @@ -399,17 +399,13 @@ void ike_alg_show_connection(struct connection *c, const char *instance) st = state_with_serialno(c->newest_isakmp_sa); if (st) whack_log(RC_COMMENT - , "\"%s\"%s: IKE algorithm newest: %s_%d-%s-%s" + , "\"%s\"%s: IKE algorithm newest: %s-%d/%s/%s" , c->name , instance , enum_show(&oakley_enc_names, st->st_oakley.encrypt) - +7 /* strlen("OAKLEY_") */ - /* , st->st_oakley.encrypter->keydeflen */ , st->st_oakley.enckeylen , enum_show(&oakley_hash_names, st->st_oakley.hash) - +7 /* strlen("OAKLEY_") */ , enum_show(&oakley_group_names, st->st_oakley.group->group) - +13 /* strlen("OAKLEY_GROUP_") */ ); } diff --git a/src/pluto/kernel_alg.c b/src/pluto/kernel_alg.c index 63fb150d4..eefc0182b 100644 --- a/src/pluto/kernel_alg.c +++ b/src/pluto/kernel_alg.c @@ -510,19 +510,16 @@ kernel_alg_show_connection(struct connection *c, const char *instance) st = state_with_serialno(c->newest_ipsec_sa); if (st && st->st_esp.present) whack_log(RC_COMMENT - , "\"%s\"%s: ESP algorithm newest: %s_%d-%s; pfsgroup=%s" + , "\"%s\"%s: ESP algorithm newest: %s-%d/%s/%s" , c->name , instance , enum_show(&esp_transformid_names, st->st_esp.attrs.transid) - +4 /* strlen("ESP_") */ , st->st_esp.attrs.key_len - , enum_show(&auth_alg_names, st->st_esp.attrs.auth)+ - +15 /* strlen("AUTH_ALGORITHM_") */ + , enum_show(&auth_alg_names, st->st_esp.attrs.auth) , c->policy & POLICY_PFS ? c->alg_info_esp->esp_pfsgroup ? enum_show(&oakley_group_names, c->alg_info_esp->esp_pfsgroup) - +13 /*strlen("OAKLEY_GROUP_")*/ : "" : "" );