📄 alg_info.c
字号:
/* * Algorithm info parsing and creation functions * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> * * alg_info.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp * * 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 <stddef.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/stat.h>#include <netinet/in.h>#include <arpa/inet.h>#include <ctype.h>#include <openswan.h>#include <openswan/ipsec_policy.h>#include <openswan/passert.h>#include <pfkeyv2.h>#include "constants.h"#include "alg_info.h"#include "oswlog.h"#include "oswalloc.h"/* abstract reference */struct oakley_group_desc;/* sadb/ESP aa attrib converters */intalg_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 */intalg_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 */intalg_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 0x00ffff01static intealg_getbyname_esp(const char *const str, int len){ int ret=-1; if (!str||!*str) goto out; /* leave special case for eg: "id248" string */ if (strcmp("id", str)==0) return ESP_MAGIC_ID; ret=alg_enum_search_prefix(&esp_transformid_names, "ESP_", str, len);out: return ret;}/* * Search auth_alg_names for a match, eg: * "md5" <=> "AUTH_ALGORITHM_HMAC_MD5" */static intaalg_getbyname_esp(const char *const str, int len){ int ret=-1; unsigned num; if (!str||!*str) goto out; ret=alg_enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_HMAC_",str,len); if (ret>=0) goto out; ret=alg_enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_",str,len); if (ret>=0) goto out; sscanf(str, "id%d%n", &ret, &num); if (ret >=0 && num!=strlen(str)) ret=-1;out: return ret;}static intmodp_getbyname_esp(const char *const str, int len){ int ret=-1; if (!str||!*str) goto out; ret=alg_enum_search_prefix(&oakley_group_names,"OAKLEY_GROUP_",str,len); if (ret>=0) goto out; ret=alg_enum_search_ppfix(&oakley_group_names, "OAKLEY_GROUP_", " (extension)", str, len);out: return ret;}void alg_info_free(struct alg_info *alg_info) { pfreeany(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){ 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)); /* 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; /* 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));}/* * Add ESP alg info _with_ logic (policy): */static voidalg_info_esp_add (struct alg_info *alg_info, int ealg_id, int ek_bits, int aalg_id, int ak_bits, int modp_id, bool permit_manconn){ /* Policy: default to 3DES */ if (ealg_id==0) ealg_id=ESP_3DES; if (ealg_id>0) { if(aalg_id > 0 || (permit_manconn && 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); } }}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];}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){ 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: { 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -