conf.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602
  1. /* conf.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #if !defined(WOLFSSL_CONF_INCLUDED)
  26. #ifndef WOLFSSL_IGNORE_FILE_WARN
  27. #warning conf.c does not need to be compiled separately from ssl.c
  28. #endif
  29. #else
  30. /*******************************************************************************
  31. * START OF TXT_DB API
  32. ******************************************************************************/
  33. #if defined(OPENSSL_ALL) && !defined(NO_BIO)
  34. /**
  35. * This function reads a tab delimetered CSV input and returns
  36. * a populated WOLFSSL_TXT_DB structure.
  37. * @param in Tab delimetered CSV input
  38. * @param num Number of fields in each row.
  39. * @return
  40. */
  41. WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num)
  42. {
  43. WOLFSSL_TXT_DB *ret = NULL;
  44. char *buf = NULL;
  45. char *bufEnd = NULL;
  46. char *idx = NULL;
  47. char* lineEnd = NULL;
  48. int bufSz;
  49. int failed = 1;
  50. /* Space in front of str reserved for field pointers + \0 */
  51. int fieldsSz = (num + 1) * sizeof(char *);
  52. WOLFSSL_ENTER("wolfSSL_TXT_DB_read");
  53. if (!in || num <= 0 || num > WOLFSSL_TXT_DB_MAX_FIELDS) {
  54. WOLFSSL_MSG("Bad parameter or too many fields");
  55. return NULL;
  56. }
  57. if (!(ret = (WOLFSSL_TXT_DB*)XMALLOC(sizeof(WOLFSSL_TXT_DB), NULL,
  58. DYNAMIC_TYPE_OPENSSL))) {
  59. WOLFSSL_MSG("malloc error");
  60. goto error;
  61. }
  62. XMEMSET (ret, 0, sizeof(WOLFSSL_TXT_DB));
  63. ret->num_fields = num;
  64. if (!(ret->data = wolfSSL_sk_WOLFSSL_STRING_new())) {
  65. WOLFSSL_MSG("wolfSSL_sk_WOLFSSL_STRING_new error");
  66. goto error;
  67. }
  68. bufSz = wolfSSL_BIO_get_len(in);
  69. if (bufSz <= 0 ||
  70. !(buf = (char*)XMALLOC(bufSz+1, NULL,
  71. DYNAMIC_TYPE_TMP_BUFFER))) {
  72. WOLFSSL_MSG("malloc error or no data in BIO");
  73. goto error;
  74. }
  75. if (wolfSSL_BIO_read(in, buf, bufSz) != bufSz) {
  76. WOLFSSL_MSG("malloc error or no data in BIO");
  77. goto error;
  78. }
  79. buf[bufSz] = '\0';
  80. idx = buf;
  81. for (bufEnd = buf + bufSz; idx < bufEnd; idx = lineEnd + 1) {
  82. char* strBuf = NULL;
  83. char** fieldPtr = NULL;
  84. int fieldPtrIdx = 0;
  85. char* fieldCheckIdx = NULL;
  86. lineEnd = XSTRNSTR(idx, "\n", (unsigned int)(bufEnd - idx));
  87. if (!lineEnd)
  88. lineEnd = bufEnd;
  89. if (idx == lineEnd) /* empty line */
  90. continue;
  91. if (*idx == '#')
  92. continue;
  93. *lineEnd = '\0';
  94. strBuf = (char*)XMALLOC(fieldsSz + lineEnd - idx + 1, NULL,
  95. DYNAMIC_TYPE_OPENSSL);
  96. if (!strBuf) {
  97. WOLFSSL_MSG("malloc error");
  98. goto error;
  99. }
  100. XMEMCPY(strBuf + fieldsSz, idx, lineEnd - idx + 1); /* + 1 for NULL */
  101. XMEMSET(strBuf, 0, fieldsSz);
  102. /* Check for appropriate number of fields */
  103. fieldPtr = (char**)strBuf;
  104. fieldCheckIdx = strBuf + fieldsSz;
  105. fieldPtr[fieldPtrIdx++] = fieldCheckIdx;
  106. while (*fieldCheckIdx != '\0') {
  107. /* Handle escaped tabs */
  108. if (*fieldCheckIdx == '\t' && fieldCheckIdx[-1] != '\\') {
  109. fieldPtr[fieldPtrIdx++] = fieldCheckIdx + 1;
  110. *fieldCheckIdx = '\0';
  111. if (fieldPtrIdx > num) {
  112. WOLFSSL_MSG("too many fields");
  113. XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL);
  114. goto error;
  115. }
  116. }
  117. fieldCheckIdx++;
  118. }
  119. if (fieldPtrIdx != num) {
  120. WOLFSSL_MSG("wrong number of fields");
  121. XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL);
  122. goto error;
  123. }
  124. if (wolfSSL_sk_push(ret->data, strBuf) != WOLFSSL_SUCCESS) {
  125. WOLFSSL_MSG("wolfSSL_sk_push error");
  126. XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL);
  127. goto error;
  128. }
  129. }
  130. failed = 0;
  131. error:
  132. if (failed && ret) {
  133. XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL);
  134. ret = NULL;
  135. }
  136. if (buf) {
  137. XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  138. }
  139. return ret;
  140. }
  141. long wolfSSL_TXT_DB_write(WOLFSSL_BIO *out, WOLFSSL_TXT_DB *db)
  142. {
  143. const WOLF_STACK_OF(WOLFSSL_STRING)* data;
  144. long totalLen = 0;
  145. char buf[512]; /* Should be more than enough for a single row */
  146. char* bufEnd = buf + sizeof(buf);
  147. int sz;
  148. int i;
  149. WOLFSSL_ENTER("wolfSSL_TXT_DB_write");
  150. if (!out || !db || !db->num_fields) {
  151. WOLFSSL_MSG("Bad parameter");
  152. return WOLFSSL_FAILURE;
  153. }
  154. data = db->data;
  155. while (data) {
  156. char** fields = (char**)data->data.string;
  157. char* idx = buf;
  158. if (!fields) {
  159. WOLFSSL_MSG("Missing row");
  160. return WOLFSSL_FAILURE;
  161. }
  162. for (i = 0; i < db->num_fields; i++) {
  163. const char* fieldValue = fields[i];
  164. if (!fieldValue) {
  165. fieldValue = "";
  166. }
  167. /* Copy over field escaping tabs */
  168. while (*fieldValue != '\0') {
  169. if (idx+1 < bufEnd) {
  170. if (*fieldValue == '\t')
  171. *idx++ = '\\';
  172. *idx++ = *fieldValue++;
  173. }
  174. else {
  175. WOLFSSL_MSG("Data row is too big");
  176. return WOLFSSL_FAILURE;
  177. }
  178. }
  179. if (idx < bufEnd) {
  180. *idx++ = '\t';
  181. }
  182. else {
  183. WOLFSSL_MSG("Data row is too big");
  184. return WOLFSSL_FAILURE;
  185. }
  186. }
  187. idx[-1] = '\n';
  188. sz = (int)(idx - buf);
  189. if (wolfSSL_BIO_write(out, buf, sz) != sz) {
  190. WOLFSSL_MSG("wolfSSL_BIO_write error");
  191. return WOLFSSL_FAILURE;
  192. }
  193. totalLen += sz;
  194. data = data->next;
  195. }
  196. return totalLen;
  197. }
  198. int wolfSSL_TXT_DB_insert(WOLFSSL_TXT_DB *db, WOLFSSL_STRING *row)
  199. {
  200. WOLFSSL_ENTER("wolfSSL_TXT_DB_insert");
  201. if (!db || !row || !db->data) {
  202. WOLFSSL_MSG("Bad parameter");
  203. return WOLFSSL_FAILURE;
  204. }
  205. if (wolfSSL_sk_push(db->data, row) != WOLFSSL_SUCCESS) {
  206. WOLFSSL_MSG("wolfSSL_sk_push error");
  207. return WOLFSSL_FAILURE;
  208. }
  209. return WOLFSSL_SUCCESS;
  210. }
  211. void wolfSSL_TXT_DB_free(WOLFSSL_TXT_DB *db)
  212. {
  213. WOLFSSL_ENTER("wolfSSL_TXT_DB_free");
  214. if (db) {
  215. if (db->data) {
  216. wolfSSL_sk_pop_free(db->data, NULL);
  217. }
  218. XFREE(db, NULL, DYNAMIC_TYPE_OPENSSL);
  219. }
  220. }
  221. int wolfSSL_TXT_DB_create_index(WOLFSSL_TXT_DB *db, int field,
  222. void* qual, wolf_sk_hash_cb hash, wolf_lh_compare_cb cmp)
  223. {
  224. WOLFSSL_ENTER("wolfSSL_TXT_DB_create_index");
  225. (void)qual;
  226. (void)cmp;
  227. if (!db || !hash || !cmp || field >= db->num_fields || field < 0) {
  228. WOLFSSL_MSG("Bad parameter");
  229. return WOLFSSL_FAILURE;
  230. }
  231. db->hash_fn[field] = hash;
  232. return WOLFSSL_SUCCESS;
  233. }
  234. WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx,
  235. WOLFSSL_STRING *value)
  236. {
  237. WOLFSSL_ENTER("wolfSSL_TXT_DB_get_by_index");
  238. if (!db || !db->data || idx < 0 || idx >= db->num_fields) {
  239. WOLFSSL_MSG("Bad parameter");
  240. return NULL;
  241. }
  242. if (!db->hash_fn[idx]) {
  243. WOLFSSL_MSG("Missing hash functions");
  244. return NULL;
  245. }
  246. /* If first data struct has correct hash function
  247. * then assume others do too */
  248. if (db->data->hash_fn != db->hash_fn[idx]) {
  249. /* Set the hash and comp functions */
  250. WOLF_STACK_OF(WOLFSSL_STRING)* data = db->data;
  251. while (data) {
  252. if (data->hash_fn != db->hash_fn[idx]) {
  253. data->hash_fn = db->hash_fn[idx];
  254. data->hash = 0;
  255. }
  256. data= data->next;
  257. }
  258. }
  259. return (WOLFSSL_STRING*) wolfSSL_lh_retrieve(db->data, value);
  260. }
  261. #endif /* OPENSSL_ALL && !NO_BIO */
  262. /*******************************************************************************
  263. * END OF TXT_DB API
  264. ******************************************************************************/
  265. /*******************************************************************************
  266. * START OF CONF API
  267. ******************************************************************************/
  268. #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
  269. || defined(HAVE_STUNNEL)
  270. #ifndef NO_WOLFSSL_STUB
  271. void wolfSSL_OPENSSL_config(char *config_name)
  272. {
  273. (void)config_name;
  274. WOLFSSL_STUB("OPENSSL_config");
  275. }
  276. #endif /* !NO_WOLFSSL_STUB */
  277. #endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || HAVE_STUNNEL*/
  278. #if !defined(NO_CERTS) && defined(OPENSSL_EXTRA) && defined(OPENSSL_ALL)
  279. /**
  280. * This is the same hashing algo for WOLFSSL_CONF_VALUE as OpenSSL
  281. */
  282. static unsigned long wolfSSL_CONF_VALUE_hash(const WOLFSSL_CONF_VALUE *val)
  283. {
  284. if (val)
  285. return (wolfSSL_LH_strhash(val->section) << 2) ^
  286. wolfSSL_LH_strhash(val->name);
  287. else
  288. return 0;
  289. }
  290. /* Use SHA[256] for hashing as OpenSSL uses a hash algorithm that is
  291. * "not as good as MD5, but still good" so using SHA should be more
  292. * than good enough for this application. The produced hashes don't
  293. * need to line up between OpenSSL and wolfSSL. The hashes are for
  294. * internal indexing only */
  295. unsigned long wolfSSL_LH_strhash(const char *str)
  296. {
  297. unsigned long ret = 0;
  298. int strLen;
  299. #if !defined(NO_SHA)
  300. wc_Sha sha;
  301. byte digest[WC_SHA_DIGEST_SIZE];
  302. #elif !defined(NO_SHA256)
  303. wc_Sha256 sha;
  304. byte digest[WC_SHA256_DIGEST_SIZE];
  305. #endif
  306. WOLFSSL_ENTER("wolfSSL_LH_strhash");
  307. if (!str)
  308. return 0;
  309. strLen = (int)XSTRLEN(str);
  310. #if !defined(NO_SHA)
  311. if (wc_InitSha_ex(&sha, NULL, 0) != 0) {
  312. WOLFSSL_MSG("SHA1 Init failed");
  313. return 0;
  314. }
  315. ret = wc_ShaUpdate(&sha, (const byte *)str, (word32)strLen);
  316. if (ret != 0) {
  317. WOLFSSL_MSG("SHA1 Update failed");
  318. } else {
  319. ret = wc_ShaFinal(&sha, digest);
  320. if (ret != 0) {
  321. WOLFSSL_MSG("SHA1 Final failed");
  322. }
  323. }
  324. wc_ShaFree(&sha);
  325. #elif !defined(NO_SHA256)
  326. if (wc_InitSha256_ex(&sha, NULL, 0) != 0) {
  327. WOLFSSL_MSG("SHA256 Init failed");
  328. return 0;
  329. }
  330. ret = wc_Sha256Update(&sha, (const byte *)str, (word32)strLen);
  331. if (ret != 0) {
  332. WOLFSSL_MSG("SHA256 Update failed");
  333. } else {
  334. ret = wc_Sha256Final(&sha, digest);
  335. if (ret != 0) {
  336. WOLFSSL_MSG("SHA256 Final failed");
  337. }
  338. }
  339. wc_Sha256Free(&sha);
  340. #endif
  341. #if !defined(NO_SHA) || !defined(NO_SHA256)
  342. if (ret != 0)
  343. return 0;
  344. /* Take first 4 bytes in small endian as unsigned long */
  345. ret = (unsigned int)digest[0];
  346. ret |= ((unsigned int)digest[1] << 8 );
  347. ret |= ((unsigned int)digest[2] << 16);
  348. ret |= ((unsigned int)digest[3] << 24);
  349. #else
  350. WOLFSSL_MSG("No SHA available for wolfSSL_LH_strhash");
  351. #endif
  352. return ret;
  353. }
  354. WOLFSSL_CONF_VALUE *wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(
  355. WOLF_LHASH_OF(WOLFSSL_CONF_VALUE) *sk, WOLFSSL_CONF_VALUE *data)
  356. {
  357. WOLFSSL_ENTER("wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve");
  358. if (!sk || !data) {
  359. WOLFSSL_MSG("Bad parameter");
  360. return NULL;
  361. }
  362. return (WOLFSSL_CONF_VALUE*)wolfSSL_lh_retrieve(sk, data);
  363. }
  364. int wolfSSL_CONF_modules_load(const WOLFSSL_CONF *cnf, const char *appname,
  365. unsigned long flags)
  366. {
  367. WOLFSSL_ENTER("wolfSSL_CONF_modules_load");
  368. WOLFSSL_MSG("All wolfSSL modules are already compiled in. "
  369. "wolfSSL_CONF_modules_load doesn't load anything new.");
  370. (void)cnf;
  371. (void)appname;
  372. (void)flags;
  373. return WOLFSSL_SUCCESS;
  374. }
  375. WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new(void)
  376. {
  377. WOLFSSL_CONF_VALUE* ret;
  378. WOLFSSL_ENTER("wolfSSL_CONF_new");
  379. ret = (WOLFSSL_CONF_VALUE*)XMALLOC(sizeof(WOLFSSL_CONF_VALUE),
  380. NULL, DYNAMIC_TYPE_OPENSSL);
  381. if (ret)
  382. XMEMSET(ret, 0, sizeof(WOLFSSL_CONF_VALUE));
  383. return ret;
  384. }
  385. int wolfSSL_CONF_add_string(WOLFSSL_CONF *conf,
  386. WOLFSSL_CONF_VALUE *section, WOLFSSL_CONF_VALUE *value)
  387. {
  388. WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
  389. if (!conf || !section || !value) {
  390. WOLFSSL_MSG("Bad parameter");
  391. return WOLFSSL_FAILURE;
  392. }
  393. sk = (WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *)section->value;
  394. value->section = section->section;
  395. if (wolfSSL_sk_CONF_VALUE_push(sk, value) != WOLFSSL_SUCCESS) {
  396. WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error");
  397. return WOLFSSL_FAILURE;
  398. }
  399. if (wolfSSL_sk_CONF_VALUE_push(conf->data, value) != WOLFSSL_SUCCESS) {
  400. WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error");
  401. return WOLFSSL_FAILURE;
  402. }
  403. return WOLFSSL_SUCCESS;
  404. }
  405. WOLFSSL_CONF_VALUE *wolfSSL_CONF_new_section(WOLFSSL_CONF *conf,
  406. const char *section)
  407. {
  408. WOLFSSL_CONF_VALUE* ret = NULL;
  409. WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
  410. int slen;
  411. WOLFSSL_ENTER("wolfSSL_CONF_new_section");
  412. if (!conf || !section) {
  413. WOLFSSL_MSG("Bad parameter");
  414. return NULL;
  415. }
  416. slen = (int)XSTRLEN(section);
  417. if (!(ret = wolfSSL_CONF_VALUE_new())) {
  418. WOLFSSL_MSG("wolfSSL_CONF_new error");
  419. goto error;
  420. }
  421. if (!(ret->section = (char*)XMALLOC(slen+1, NULL, DYNAMIC_TYPE_OPENSSL))) {
  422. WOLFSSL_MSG("section malloc error");
  423. goto error;
  424. }
  425. XMEMCPY(ret->section, section, slen+1);
  426. if (!(sk = wolfSSL_sk_CONF_VALUE_new(NULL))) {
  427. WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_new error");
  428. goto error;
  429. }
  430. ret->value = (char*)sk;
  431. if (wolfSSL_sk_CONF_VALUE_push(conf->data, ret) != WOLFSSL_SUCCESS) {
  432. WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error");
  433. goto error;
  434. }
  435. return ret;
  436. error:
  437. if (ret) {
  438. /* NULL so that wolfSSL_X509V3_conf_free doesn't attempt to free it */
  439. ret->value = NULL;
  440. wolfSSL_X509V3_conf_free(ret);
  441. }
  442. if (sk) {
  443. wolfSSL_sk_CONF_VALUE_free(sk);
  444. }
  445. return NULL;
  446. }
  447. WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf,
  448. const char *section)
  449. {
  450. WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
  451. WOLFSSL_ENTER("wolfSSL_CONF_get_section");
  452. if (!conf || !section) {
  453. WOLFSSL_MSG("Bad parameter");
  454. return NULL;
  455. }
  456. sk = conf->data;
  457. while (sk) {
  458. WOLFSSL_CONF_VALUE* val = sk->data.conf;
  459. if (val) {
  460. if (!val->name && XSTRCMP(section, val->section) == 0) {
  461. return val;
  462. }
  463. }
  464. sk = sk->next;
  465. }
  466. return NULL;
  467. }
  468. WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth)
  469. {
  470. WOLFSSL_CONF* ret;
  471. WOLFSSL_ENTER("wolfSSL_NCONF_new");
  472. if (meth) {
  473. WOLFSSL_MSG("wolfSSL does not support CONF_METHOD");
  474. }
  475. ret = (WOLFSSL_CONF*)XMALLOC(sizeof(WOLFSSL_CONF), NULL, DYNAMIC_TYPE_OPENSSL);
  476. if (ret) {
  477. XMEMSET(ret, 0, sizeof(WOLFSSL_CONF));
  478. ret->data = wolfSSL_sk_CONF_VALUE_new(NULL);
  479. if (!ret->data) {
  480. wolfSSL_NCONF_free(ret);
  481. return NULL;
  482. }
  483. }
  484. return ret;
  485. }
  486. char *wolfSSL_NCONF_get_string(const WOLFSSL_CONF *conf,
  487. const char *group, const char *name)
  488. {
  489. WOLFSSL_CONF_VALUE find_val;
  490. WOLFSSL_CONF_VALUE *val;
  491. WOLFSSL_ENTER("wolfSSL_NCONF_get_string");
  492. if (!conf) {
  493. #ifdef HAVE_SECURE_GETENV
  494. return secure_getenv(name);
  495. #else
  496. WOLFSSL_MSG("Missing secure_getenv");
  497. return NULL;
  498. #endif
  499. }
  500. find_val.name = (char *)name;
  501. if (group) {
  502. find_val.section = (char *)group;
  503. val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val);
  504. if (val)
  505. return val->value;
  506. if (XSTRCMP(group, "ENV") == 0) {
  507. #ifdef HAVE_SECURE_GETENV
  508. return secure_getenv(name);
  509. #else
  510. WOLFSSL_MSG("Missing secure_getenv");
  511. return NULL;
  512. #endif
  513. }
  514. }
  515. find_val.section = (char *)"default";
  516. val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val);
  517. if (val)
  518. return val->value;
  519. else
  520. return NULL;
  521. }
  522. int wolfSSL_NCONF_get_number(const CONF *conf, const char *group,
  523. const char *name, long *result)
  524. {
  525. char *str;
  526. WOLFSSL_ENTER("wolfSSL_NCONF_get_number");
  527. if (!conf || !name || !result) {
  528. WOLFSSL_MSG("Bad parameter");
  529. return WOLFSSL_FAILURE;
  530. }
  531. if (!(str = wolfSSL_NCONF_get_string(conf, group, name))) {
  532. WOLFSSL_MSG("wolfSSL_NCONF_get_string error");
  533. return WOLFSSL_FAILURE;
  534. }
  535. *result = atol(str);
  536. return WOLFSSL_SUCCESS;
  537. }
  538. /**
  539. * The WOLFSSL_CONF->value member is treated as a
  540. * WOLFSSL_STACK_OF(WOLFSSL_CONF_VALUE) which becomes
  541. * the return value.
  542. * @param conf
  543. * @param section
  544. * @return WOLFSSL_STACK_OF(WOLFSSL_CONF_VALUE)
  545. */
  546. WOLFSSL_STACK *wolfSSL_NCONF_get_section(
  547. const WOLFSSL_CONF *conf, const char *section)
  548. {
  549. WOLFSSL_CONF_VALUE *val;
  550. WOLFSSL_CONF_VALUE find_val;
  551. WOLFSSL_ENTER("wolfSSL_NCONF_get_section");
  552. if (!conf || !section) {
  553. WOLFSSL_MSG("Bad parameter");
  554. return NULL;
  555. }
  556. find_val.name = NULL;
  557. find_val.section = (char*)section;
  558. val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val);
  559. if (val)
  560. return (WOLFSSL_STACK*)val->value;
  561. else
  562. return NULL;
  563. }
  564. #if !defined(NO_BIO)
  565. static WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section,
  566. char* name, char* value)
  567. {
  568. WOLFSSL_CONF_VALUE* ret;
  569. int len;
  570. WOLFSSL_ENTER("wolfSSL_CONF_VALUE_new_values");
  571. if (!(ret = wolfSSL_CONF_VALUE_new())) {
  572. WOLFSSL_MSG("wolfSSL_CONF_VALUE_new error");
  573. return NULL;
  574. }
  575. if (section) {
  576. len = (int)XSTRLEN(section);
  577. ret->section = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL);
  578. if (!ret->section) {
  579. WOLFSSL_MSG("malloc error");
  580. wolfSSL_X509V3_conf_free(ret);
  581. return NULL;
  582. }
  583. XMEMCPY(ret->section, section, len+1);
  584. }
  585. if (name) {
  586. len = (int)XSTRLEN(name);
  587. ret->name = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL);
  588. if (!ret->name) {
  589. WOLFSSL_MSG("malloc error");
  590. wolfSSL_X509V3_conf_free(ret);
  591. return NULL;
  592. }
  593. XMEMCPY(ret->name, name, len+1);
  594. }
  595. if (value) {
  596. len = (int)XSTRLEN(value);
  597. ret->value = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL);
  598. if (!ret->value) {
  599. WOLFSSL_MSG("malloc error");
  600. wolfSSL_X509V3_conf_free(ret);
  601. return NULL;
  602. }
  603. XMEMCPY(ret->value, value, len+1);
  604. }
  605. return ret;
  606. }
  607. static char* expandValue(WOLFSSL_CONF *conf, const char* section,
  608. char *str)
  609. {
  610. int strLen = (int)XSTRLEN(str);
  611. char* ret = NULL;
  612. /* Check to see if there is anything to expand */
  613. if (XSTRNSTR(str, "$", strLen)) {
  614. int idx = 0;
  615. char* strIdx = str;
  616. ret = (char*)XMALLOC(strLen + 1, NULL, DYNAMIC_TYPE_OPENSSL);
  617. if (!ret) {
  618. WOLFSSL_MSG("malloc error");
  619. return str;
  620. }
  621. while (*strIdx) {
  622. if (*strIdx == '$') {
  623. /* Expand variable */
  624. char* startIdx = ++strIdx;
  625. char* endIdx;
  626. const char* s = section;
  627. const char* value;
  628. char prevValue;
  629. if (*startIdx == '{') {
  630. /* First read the section.
  631. * format: ${section_name::var_name} */
  632. s = ++startIdx;
  633. while (*strIdx && *strIdx != ':') strIdx++;
  634. if (!*strIdx || s == strIdx || strIdx[1] != ':') {
  635. WOLFSSL_MSG("invalid section name in "
  636. "variable expansion");
  637. goto expand_cleanup;
  638. }
  639. *strIdx = '\0';
  640. strIdx += 2;
  641. startIdx = strIdx;
  642. }
  643. while (*strIdx && (XISALNUM(*strIdx) || *strIdx == '_'))
  644. strIdx++;
  645. endIdx = strIdx;
  646. if (startIdx == endIdx) {
  647. WOLFSSL_MSG("invalid variable name in config");
  648. goto expand_cleanup;
  649. }
  650. if (s != section) {
  651. /* We are expecting a trailing '}' */
  652. if (*strIdx != '}') {
  653. WOLFSSL_MSG("Missing '}' in variable");
  654. goto expand_cleanup;
  655. }
  656. strIdx++;
  657. }
  658. /* Save char value at the end of the name so that we can place
  659. * a null char there. */
  660. prevValue = *endIdx;
  661. *endIdx = '\0';
  662. value = wolfSSL_NCONF_get_string(conf, s, startIdx);
  663. *endIdx = prevValue;
  664. /* Skip copy if no value or zero-length value */
  665. if (value && *value) {
  666. int valueLen = (int)XSTRLEN(value);
  667. char* newRet;
  668. /* This will allocate slightly more memory than necessary
  669. * but better be safe */
  670. strLen += valueLen;
  671. newRet = (char*)XREALLOC(ret, strLen + 1, NULL,
  672. DYNAMIC_TYPE_OPENSSL);
  673. if (!newRet) {
  674. WOLFSSL_MSG("realloc error");
  675. goto expand_cleanup;
  676. }
  677. ret = newRet;
  678. XMEMCPY(ret + idx, value, valueLen);
  679. idx += valueLen;
  680. }
  681. }
  682. else {
  683. ret[idx++] = *strIdx++;
  684. }
  685. }
  686. ret[idx] = '\0';
  687. }
  688. return ret ? ret : str;
  689. expand_cleanup:
  690. if (ret)
  691. XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL);
  692. return NULL;
  693. }
  694. #define SKIP_WHITESPACE(idx, max_idx) \
  695. while ((idx) < (max_idx) && (*(idx) == ' ' || *(idx) == '\t')) \
  696. {(idx)++;}
  697. int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline)
  698. {
  699. int ret = WOLFSSL_FAILURE;
  700. WOLFSSL_BIO *in = NULL;
  701. char* buf = NULL;
  702. char* idx = NULL;
  703. char* bufEnd = NULL;
  704. CONF_VALUE* section = NULL;
  705. long line = 0;
  706. int bufLen = 0;
  707. if (!conf || !file) {
  708. WOLFSSL_MSG("Bad parameter");
  709. return WOLFSSL_FAILURE;
  710. }
  711. /* Open file */
  712. if (!(in = wolfSSL_BIO_new_file(file, "rb"))) {
  713. WOLFSSL_MSG("wolfSSL_BIO_new_file error");
  714. return WOLFSSL_FAILURE;
  715. }
  716. /* Read file */
  717. bufLen = wolfSSL_BIO_get_len(in);
  718. if (bufLen <= 0) {
  719. WOLFSSL_MSG("wolfSSL_BIO_get_len error");
  720. goto cleanup;
  721. }
  722. if (!(buf = (char*)XMALLOC(bufLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER))) {
  723. WOLFSSL_MSG("malloc error");
  724. goto cleanup;
  725. }
  726. if (wolfSSL_BIO_read(in, buf, bufLen) != bufLen) {
  727. WOLFSSL_MSG("wolfSSL_BIO_read error");
  728. goto cleanup;
  729. }
  730. if (!(section = wolfSSL_CONF_new_section(conf, "default"))) {
  731. WOLFSSL_MSG("wolfSSL_CONF_new_section error");
  732. goto cleanup;
  733. }
  734. /* LETS START READING SOME CONFIGS */
  735. idx = buf;
  736. bufEnd = buf + bufLen;
  737. while (idx < bufEnd) {
  738. char* lineEnd = XSTRNSTR(idx, "\n", (unsigned int)(bufEnd - idx));
  739. char* maxIdx;
  740. if (!lineEnd)
  741. lineEnd = bufEnd; /* Last line in file */
  742. maxIdx = XSTRNSTR(idx, "#", (unsigned int)(lineEnd - idx));
  743. if (!maxIdx)
  744. maxIdx = lineEnd;
  745. line++;
  746. SKIP_WHITESPACE(idx, maxIdx);
  747. if (idx == maxIdx) {
  748. /* Empty line */
  749. idx = lineEnd + 1;
  750. continue;
  751. }
  752. if (*idx == '[') {
  753. /* New section. Spaces not allowed in section name. */
  754. char* sectionName;
  755. int sectionNameLen;
  756. if (idx < maxIdx)
  757. idx++;
  758. else {
  759. WOLFSSL_MSG("Invalid section definition.");
  760. goto cleanup;
  761. }
  762. SKIP_WHITESPACE(idx, maxIdx);
  763. sectionName = idx;
  764. /* Find end of section name */
  765. while (idx < maxIdx && *idx != ' ' && *idx != ']')
  766. idx++;
  767. sectionNameLen = (int)(idx - sectionName);
  768. SKIP_WHITESPACE(idx, maxIdx);
  769. if (*idx != ']') {
  770. WOLFSSL_MSG("Section definition error. "
  771. "Closing brace not found.");
  772. goto cleanup;
  773. }
  774. sectionName[sectionNameLen] = '\0';
  775. if (!(section = wolfSSL_CONF_get_section(conf, sectionName))) {
  776. section = wolfSSL_CONF_new_section(conf, sectionName);
  777. if (!section)
  778. goto cleanup;
  779. }
  780. }
  781. else {
  782. char* name;
  783. int nameLen;
  784. char* value;
  785. char* exValue; /* expanded value */
  786. int valueLen;
  787. WOLFSSL_CONF_VALUE* newVal = NULL;
  788. SKIP_WHITESPACE(idx, maxIdx);
  789. name = idx;
  790. /* Find end of name */
  791. while (idx < maxIdx && *idx != ' ' && *idx != '=')
  792. idx++;
  793. nameLen = (int)(idx - name);
  794. SKIP_WHITESPACE(idx, maxIdx);
  795. if (*idx != '=') {
  796. WOLFSSL_MSG("Missing equals sign");
  797. goto cleanup;
  798. }
  799. idx++;
  800. SKIP_WHITESPACE(idx, maxIdx);
  801. value = idx;
  802. /* Find end of value */
  803. idx = maxIdx-1;
  804. while (idx >= value && (*idx == ' ' || *idx == '\t' || *idx == '\r'))
  805. idx--;
  806. valueLen = (int)(idx - value + 1);
  807. /* Sanity checks */
  808. if (nameLen <= 0 || valueLen <= 0) {
  809. WOLFSSL_MSG("Sanity checks failed");
  810. goto cleanup;
  811. }
  812. name[nameLen] = '\0';
  813. value[valueLen] = '\0';
  814. if (!(exValue = expandValue(conf, section->section, value))) {
  815. WOLFSSL_MSG("Variable expansion failed");
  816. goto cleanup;
  817. }
  818. if (!(newVal = wolfSSL_CONF_VALUE_new_values(NULL,
  819. name, exValue))) {
  820. WOLFSSL_MSG("wolfSSL_CONF_VALUE_new_values error");
  821. if (exValue != value)
  822. XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL);
  823. goto cleanup;
  824. }
  825. if (exValue != value)
  826. XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL);
  827. if (wolfSSL_CONF_add_string(conf, section, newVal) !=
  828. WOLFSSL_SUCCESS) {
  829. WOLFSSL_MSG("wolfSSL_CONF_add_string error");
  830. goto cleanup;
  831. }
  832. }
  833. idx = lineEnd + 1;
  834. }
  835. ret = WOLFSSL_SUCCESS;
  836. cleanup:
  837. if (in)
  838. wolfSSL_BIO_free(in);
  839. if (buf)
  840. XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  841. if (eline)
  842. *eline = line;
  843. return ret;
  844. }
  845. #endif /* !NO_BIO */
  846. void wolfSSL_NCONF_free(WOLFSSL_CONF *conf)
  847. {
  848. WOLFSSL_ENTER("wolfSSL_NCONF_free");
  849. if (conf) {
  850. wolfSSL_sk_CONF_VALUE_free(conf->data);
  851. XFREE(conf, NULL, DYNAMIC_TYPE_OPENSSL);
  852. }
  853. }
  854. void wolfSSL_X509V3_conf_free(WOLFSSL_CONF_VALUE *val)
  855. {
  856. WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
  857. if (val) {
  858. if (val->name) {
  859. /* Not a section. Don't free section as it is a shared pointer. */
  860. XFREE(val->name, NULL, DYNAMIC_TYPE_OPENSSL);
  861. if (val->value)
  862. XFREE(val->value, NULL, DYNAMIC_TYPE_OPENSSL);
  863. }
  864. else {
  865. /* Section so val->value is a stack */
  866. if (val->section)
  867. XFREE(val->section, NULL, DYNAMIC_TYPE_OPENSSL);
  868. /* Only free the stack structures. The contained conf values
  869. * will be freed in wolfSSL_NCONF_free */
  870. sk = (WOLF_STACK_OF(WOLFSSL_CONF_VALUE)*)val->value;
  871. while (sk) {
  872. WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *tmp = sk->next;
  873. XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
  874. sk = tmp;
  875. }
  876. }
  877. XFREE(val, NULL, DYNAMIC_TYPE_OPENSSL);
  878. }
  879. }
  880. WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(
  881. WOLF_SK_COMPARE_CB(WOLFSSL_CONF_VALUE, compFunc))
  882. {
  883. WOLFSSL_STACK* ret;
  884. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_new");
  885. ret = wolfSSL_sk_new_node(NULL);
  886. if (!ret)
  887. return NULL;
  888. ret->hash_fn = (wolf_sk_hash_cb)wolfSSL_CONF_VALUE_hash;
  889. ret->type = STACK_TYPE_CONF_VALUE;
  890. (void)compFunc;
  891. return ret;
  892. }
  893. /* Free the structure for WOLFSSL_CONF_VALUE stack
  894. *
  895. * sk stack to free nodes in
  896. */
  897. void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk)
  898. {
  899. WOLFSSL_STACK* tmp;
  900. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_free");
  901. if (sk == NULL)
  902. return;
  903. /* parse through stack freeing each node */
  904. while (sk) {
  905. tmp = sk->next;
  906. wolfSSL_X509V3_conf_free(sk->data.conf);
  907. XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
  908. sk = tmp;
  909. }
  910. }
  911. int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk)
  912. {
  913. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_num");
  914. if (sk)
  915. return wolfSSL_sk_num(sk);
  916. return 0;
  917. }
  918. WOLFSSL_CONF_VALUE *wolfSSL_sk_CONF_VALUE_value(const WOLFSSL_STACK *sk, int i)
  919. {
  920. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_value");
  921. if (sk)
  922. return (WOLFSSL_CONF_VALUE*)wolfSSL_sk_value(sk, i);
  923. return NULL;
  924. }
  925. /* return 1 on success 0 on fail */
  926. int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk,
  927. WOLFSSL_CONF_VALUE* val)
  928. {
  929. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_push");
  930. if (sk == NULL || val == NULL) {
  931. return WOLFSSL_FAILURE;
  932. }
  933. return wolfSSL_sk_push(sk, val);
  934. }
  935. #endif /* !NO_CERTS && OPENSSL_EXTRA && OPENSSL_ALL */
  936. #ifdef OPENSSL_EXTRA
  937. #ifndef NO_WOLFSSL_STUB
  938. /* Returns default file name and path of config file. However
  939. a wolfssl.cnf file is not currently supported */
  940. char* wolfSSL_CONF_get1_default_config_file(void)
  941. {
  942. WOLFSSL_ENTER("wolfSSL_CONF_get1_default_config_file");
  943. WOLFSSL_STUB("CONF_get1_default_config_file");
  944. return NULL;
  945. }
  946. #endif
  947. /**
  948. * Allocate WOLFSSL_CONF_CTX instance
  949. * @return pointer to WOLFSSL_CONF_CTX structure on success and NULL on fail
  950. */
  951. WOLFSSL_CONF_CTX* wolfSSL_CONF_CTX_new(void)
  952. {
  953. WOLFSSL_CONF_CTX* cctx;
  954. WOLFSSL_ENTER("wolfSSL_CONF_CTX_new");
  955. cctx = (WOLFSSL_CONF_CTX*)XMALLOC(sizeof(WOLFSSL_CONF_CTX), NULL,
  956. DYNAMIC_TYPE_OPENSSL);
  957. if (!cctx) {
  958. WOLFSSL_MSG("malloc error");
  959. return NULL;
  960. }
  961. XMEMSET(cctx, 0, sizeof(WOLFSSL_CONF_CTX));
  962. return cctx;
  963. }
  964. /**
  965. * Release WOLFSSL_CONF_CTX instance
  966. * @param cctx a pointer to WOLFSSL_CONF_CTX structure to be freed
  967. */
  968. void wolfSSL_CONF_CTX_free(WOLFSSL_CONF_CTX* cctx)
  969. {
  970. WOLFSSL_ENTER("wolfSSL_CONF_CTX_free");
  971. if (cctx) {
  972. XFREE(cctx, NULL, DYNAMIC_TYPE_OPENSSL);
  973. }
  974. WOLFSSL_LEAVE("wolfSSL_CONF_CTX_free", 1);
  975. }
  976. /**
  977. * Set WOLFSSL_CTX instance to WOLFSSL_CONF_CTX
  978. * @param cctx a pointer to WOLFSSL_CONF_CTX structure to set a WOLFSSL_CTX
  979. * pointer to its ctx
  980. * @param ctx a pointer to WOLFSSL_CTX structure to be set
  981. */
  982. void wolfSSL_CONF_CTX_set_ssl_ctx(WOLFSSL_CONF_CTX* cctx, WOLFSSL_CTX *ctx)
  983. {
  984. WOLFSSL_ENTER("wolfSSL_CONF_CTX_set_ssl_ctx");
  985. /* sanity check */
  986. if (cctx == NULL) {
  987. WOLFSSL_MSG("cctx is null");
  988. return;
  989. }
  990. cctx->ctx = ctx;
  991. WOLFSSL_LEAVE("wolfSSL_CONF_CTX_set_ssl_ctx", 1);
  992. }
  993. /**
  994. * set flag value into WOLFSSL_CONF_CTX
  995. * @param cctx a pointer to WOLFSSL_CONF_CTX structure to be set
  996. * @param flags falg value to be OR'd
  997. * @return OR'd flag value, otherwise 0
  998. */
  999. unsigned int wolfSSL_CONF_CTX_set_flags(WOLFSSL_CONF_CTX* cctx,
  1000. unsigned int flags)
  1001. {
  1002. /* sanity check */
  1003. if (cctx == NULL)
  1004. return 0;
  1005. cctx->flags |= flags;
  1006. return cctx->flags;
  1007. }
  1008. /**
  1009. * finish configuration command operation
  1010. * @param cctx a pointer to WOLFSSL_CONF_CTX structure to be set
  1011. * @return WOLFSSL_SUCCESS on success
  1012. */
  1013. int wolfSSL_CONF_CTX_finish(WOLFSSL_CONF_CTX* cctx)
  1014. {
  1015. (void)cctx;
  1016. return WOLFSSL_SUCCESS;
  1017. }
  1018. /*
  1019. * The following definitions and static functions are used for
  1020. * wolfSSL_CONF_cmd() to handle command.
  1021. *
  1022. * Definitions below are a part of conf_cmds_tbl[] contents.
  1023. * WOLFSSL_CONF_FILE_CMDx represents command name in configuration file
  1024. * WOLFSSL_CONF_CMDL_CMDx represents command name on command line
  1025. *
  1026. * The static functions after the definition section process
  1027. * those FILE or CMDL which are defined in the conf_cmds_tbl.
  1028. *
  1029. * To add a new command handling:
  1030. * 1. Add new #define to a section of WOLFSSL_CONF_FILE_CMD* and
  1031. * WOLFSSL_CONF_CMDL_CMD*
  1032. * 2. Add new static function after #define section, before
  1033. * "typedef struct conf_cmd_tbl {" line
  1034. * 3. Add new entry to conf_cmds_tbl[] by following other command entries
  1035. */
  1036. #define WOLFSSL_CONF_FILE_CMD1 "Curves"
  1037. #define WOLFSSL_CONF_FILE_CMD2 "Certificate"
  1038. #define WOLFSSL_CONF_FILE_CMD3 "PrivateKey"
  1039. #define WOLFSSL_CONF_FILE_CMD4 "Protocol"
  1040. #define WOLFSSL_CONF_FILE_CMD5 "Options"
  1041. #define WOLFSSL_CONF_FILE_CMD6 "ServerInfoFile"
  1042. #define WOLFSSL_CONF_FILE_CMD7 "SignatureAlgorithms"
  1043. #define WOLFSSL_CONF_FILE_CMD8 "ClientSignatureAlgorithms"
  1044. #define WOLFSSL_CONF_FILE_CMD9 "CipherString"
  1045. #define WOLFSSL_CONF_CMDL_CMD1 "curves"
  1046. #define WOLFSSL_CONF_CMDL_CMD2 "cert"
  1047. #define WOLFSSL_CONF_CMDL_CMD3 "key"
  1048. #define WOLFSSL_CONF_CMDL_CMD4 NULL
  1049. #define WOLFSSL_CONF_CMDL_CMD5 NULL
  1050. #define WOLFSSL_CONF_CMDL_CMD6 NULL
  1051. #define WOLFSSL_CONF_CMDL_CMD7 "sigalgs"
  1052. #define WOLFSSL_CONF_CMDL_CMD8 "client_sigalgs"
  1053. #define WOLFSSL_CONF_CMDL_CMD9 "cipher"
  1054. #if !defined(NO_DH) && !defined(NO_BIO)
  1055. #define WOLFSSL_CONF_FILE_CMD10 "DHParameters"
  1056. #define WOLFSSL_CONF_CMDL_CMD10 "dhparam"
  1057. #endif
  1058. #ifdef HAVE_ECC
  1059. #define WOLFSSL_CONF_FILE_CMD11 "ECDHParameters"
  1060. #define WOLFSSL_CONF_CMDL_CMD11 "named_curves"
  1061. #endif
  1062. /**
  1063. * process Cipher String command
  1064. * @param cctx a pointer to WOLFSSL_CONF_CTX structure
  1065. * @param value arguments for cmd
  1066. * @return WOLFSSL_SUCCESS on success,
  1067. * otherwise WOLFSSL_FAILURE or
  1068. * -3 if value is null or
  1069. * negative value on other failure
  1070. */
  1071. static int cmdfunc_cipherstring(WOLFSSL_CONF_CTX* cctx, const char* value)
  1072. {
  1073. int ret = -3;
  1074. WOLFSSL_ENTER("cmdfunc_cipherstring");
  1075. /* sanity check */
  1076. if (cctx == NULL)
  1077. return WOLFSSL_FAILURE;
  1078. if (value == NULL) {
  1079. WOLFSSL_MSG("bad arguments");
  1080. return ret;
  1081. }
  1082. if (cctx->ctx) {
  1083. ret = wolfSSL_CTX_set_cipher_list(cctx->ctx, value);
  1084. }
  1085. if (((cctx->ctx && ret == WOLFSSL_SUCCESS) ||
  1086. (!cctx->ctx && ret == -3)) &&
  1087. cctx->ssl) {
  1088. ret = wolfSSL_set_cipher_list(cctx->ssl, value);
  1089. }
  1090. WOLFSSL_LEAVE("cmdfunc_cipherstring", ret);
  1091. return ret;
  1092. }
  1093. /**
  1094. * process curves command
  1095. * @param cctx a pointer to WOLFSSL_CONF_CTX structure
  1096. * @param value arguments for cmd
  1097. * @return WOLFSSL_SUCCESS on success,
  1098. * otherwise WOLFSSL_FAILURE or
  1099. * -3 if value is null or
  1100. * negative value on other failure
  1101. */
  1102. #if defined(HAVE_ECC)
  1103. static int cmdfunc_curves(WOLFSSL_CONF_CTX* cctx, const char* value)
  1104. {
  1105. int ret = -3;
  1106. WOLFSSL_ENTER("cmdfunc_curves");
  1107. /* sanity check */
  1108. if (cctx == NULL)
  1109. return WOLFSSL_FAILURE;
  1110. if (value == NULL) {
  1111. WOLFSSL_MSG("bad arguments");
  1112. return ret;
  1113. }
  1114. if (cctx->ctx) {
  1115. ret = wolfSSL_CTX_set1_curves_list(cctx->ctx, value);
  1116. }
  1117. if (((cctx->ctx && ret == WOLFSSL_SUCCESS) ||
  1118. (!cctx->ctx && ret == -3)) &&
  1119. cctx->ssl) {
  1120. ret = wolfSSL_set1_curves_list(cctx->ssl, value);
  1121. }
  1122. WOLFSSL_LEAVE("cmdfunc_curves", ret);
  1123. return ret;
  1124. }
  1125. #endif
  1126. #ifndef NO_FILESYSTEM
  1127. /**
  1128. * process cert command
  1129. * @param cctx a pointer to WOLFSSL_CONF_CTX structure
  1130. * @param value arguments for cmd
  1131. * @return WOLFSSL_SUCCESS on success,
  1132. * otherwise WOLFSSL_FAILURE or
  1133. * -3 if value is null or
  1134. * negative value on other failure
  1135. */
  1136. static int cmdfunc_cert(WOLFSSL_CONF_CTX* cctx, const char* value)
  1137. {
  1138. int ret = -3;
  1139. WOLFSSL_ENTER("cmdfunc_cert");
  1140. /* sanity check */
  1141. if (cctx == NULL)
  1142. return WOLFSSL_FAILURE;
  1143. if (value == NULL) {
  1144. WOLFSSL_MSG("bad arguments");
  1145. return ret;
  1146. }
  1147. if (!(cctx->flags & WOLFSSL_CONF_FLAG_CERTIFICATE)) {
  1148. WOLFSSL_MSG("certificate flag is not set");
  1149. return -2;
  1150. }
  1151. if (cctx->ctx) {
  1152. ret = wolfSSL_CTX_use_certificate_chain_file(cctx->ctx, value);
  1153. }
  1154. if (((cctx->ctx && ret == WOLFSSL_SUCCESS) ||
  1155. (!cctx->ctx && ret == -3)) &&
  1156. cctx->ssl) {
  1157. ret = wolfSSL_use_certificate_file(cctx->ssl, value,
  1158. WOLFSSL_FILETYPE_PEM);
  1159. }
  1160. WOLFSSL_LEAVE("cmdfunc_cert", ret);
  1161. return ret;
  1162. }
  1163. /**
  1164. * process key command
  1165. * @param cctx a pointer to WOLFSSL_CONF_CTX structure
  1166. * @param value arguments for cmd
  1167. * @return WOLFSSL_SUCCESS on success,
  1168. * otherwise WOLFSSL_FAILURE or
  1169. * -3 if value is null or
  1170. * negative value on other failure
  1171. */
  1172. static int cmdfunc_key(WOLFSSL_CONF_CTX* cctx, const char* value)
  1173. {
  1174. int ret = -3;
  1175. WOLFSSL_ENTER("cmdfunc_key");
  1176. /* sanity check */
  1177. if (cctx == NULL)
  1178. return WOLFSSL_FAILURE;
  1179. if (value == NULL) {
  1180. WOLFSSL_MSG("bad arguments");
  1181. return ret;
  1182. }
  1183. if (!(cctx->flags & WOLFSSL_CONF_FLAG_CERTIFICATE)) {
  1184. WOLFSSL_MSG("certificate flag is not set");
  1185. return -2;
  1186. }
  1187. if (cctx->ctx) {
  1188. ret = wolfSSL_CTX_use_PrivateKey_file(cctx->ctx, value,
  1189. WOLFSSL_FILETYPE_PEM);
  1190. }
  1191. if (((cctx->ctx && ret == WOLFSSL_SUCCESS) ||
  1192. (!cctx->ctx && ret == -3)) &&
  1193. cctx->ssl) {
  1194. ret = wolfSSL_use_PrivateKey_file(cctx->ssl, value,
  1195. WOLFSSL_FILETYPE_PEM);
  1196. }
  1197. WOLFSSL_LEAVE("cmdfunc_key", ret);
  1198. return ret;
  1199. }
  1200. #endif /* NO_FILESYSTEM */
  1201. /**
  1202. * process DH parameter command
  1203. * @param cctx a pointer to WOLFSSL_CONF_CTX structure
  1204. * @param value arguments for cmd
  1205. * @return WOLFSSL_SUCCESS on success,
  1206. * otherwise WOLFSSL_FAILURE or
  1207. * -3 if value is null or
  1208. * negative value on other failure
  1209. */
  1210. #if !defined(NO_DH) && !defined(NO_BIO)
  1211. static int cmdfunc_dhparam(WOLFSSL_CONF_CTX* cctx, const char* value)
  1212. {
  1213. int ret = -3;
  1214. WOLFSSL_DH* dh = NULL;
  1215. WOLFSSL_BIO* bio = NULL;
  1216. WOLFSSL_MSG("cmdfunc_dhparam");
  1217. /* sanity check */
  1218. if (cctx == NULL)
  1219. return WOLFSSL_FAILURE;
  1220. if (value == NULL) {
  1221. WOLFSSL_MSG("bad arguments");
  1222. return ret;
  1223. }
  1224. if (cctx->ctx || cctx->ssl) {
  1225. bio = wolfSSL_BIO_new_file(value, "rb");
  1226. if (!bio) {
  1227. WOLFSSL_MSG("bio new file failed");
  1228. return WOLFSSL_FAILURE;
  1229. }
  1230. dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
  1231. if (!dh) {
  1232. wolfSSL_BIO_free(bio);
  1233. WOLFSSL_MSG("PEM read bio failed");
  1234. return WOLFSSL_FAILURE;
  1235. }
  1236. } else {
  1237. return 1;
  1238. }
  1239. if (cctx->ctx) {
  1240. ret = (int)wolfSSL_CTX_set_tmp_dh(cctx->ctx, dh);
  1241. }
  1242. if (((cctx->ctx && ret == WOLFSSL_SUCCESS) ||
  1243. (!cctx->ctx && ret == -3)) &&
  1244. cctx->ssl) {
  1245. ret = (int)wolfSSL_CTX_set_tmp_dh(cctx->ssl->ctx, dh);
  1246. }
  1247. if (dh)
  1248. wolfSSL_DH_free(dh);
  1249. if (bio)
  1250. wolfSSL_BIO_free(bio);
  1251. WOLFSSL_LEAVE("cmdfunc_dhparam", ret);
  1252. return ret;
  1253. }
  1254. #endif /* !NO_DH && !NO_BIO */
  1255. /**
  1256. * command table
  1257. */
  1258. typedef struct conf_cmd_tbl {
  1259. const char* file_cmd;
  1260. const char* cmdline_cmd;
  1261. word32 data_type;
  1262. int (*cmdfunc)(WOLFSSL_CONF_CTX* cctx, const char* value);
  1263. }conf_cmd_tbl;
  1264. static const conf_cmd_tbl conf_cmds_tbl[] = {
  1265. #if defined(HAVE_ECC)
  1266. /* cmd Curves */
  1267. {WOLFSSL_CONF_FILE_CMD1, WOLFSSL_CONF_CMDL_CMD1,
  1268. WOLFSSL_CONF_TYPE_STRING, cmdfunc_curves},
  1269. #endif
  1270. #if !defined(NO_FILESYSTEM)
  1271. /* cmd Certificate */
  1272. {WOLFSSL_CONF_FILE_CMD2, WOLFSSL_CONF_CMDL_CMD2,
  1273. WOLFSSL_CONF_TYPE_FILE, cmdfunc_cert},
  1274. /* cmd PrivateKey */
  1275. {WOLFSSL_CONF_FILE_CMD3, WOLFSSL_CONF_CMDL_CMD3,
  1276. WOLFSSL_CONF_TYPE_FILE, cmdfunc_key},
  1277. #endif
  1278. /* cmd Protocol */
  1279. {WOLFSSL_CONF_FILE_CMD4, WOLFSSL_CONF_CMDL_CMD4,
  1280. WOLFSSL_CONF_TYPE_STRING, NULL},
  1281. /* cmd Options */
  1282. {WOLFSSL_CONF_FILE_CMD5, WOLFSSL_CONF_CMDL_CMD5,
  1283. WOLFSSL_CONF_TYPE_STRING, NULL},
  1284. /* cmd ServerInfoFile */
  1285. {WOLFSSL_CONF_FILE_CMD6, WOLFSSL_CONF_CMDL_CMD6,
  1286. WOLFSSL_CONF_TYPE_FILE, NULL},
  1287. /* cmd SignatureAlgorithms */
  1288. {WOLFSSL_CONF_FILE_CMD7, WOLFSSL_CONF_CMDL_CMD7,
  1289. WOLFSSL_CONF_TYPE_STRING, NULL},
  1290. /* cmd ClientSignatureAlgorithms */
  1291. {WOLFSSL_CONF_FILE_CMD8, WOLFSSL_CONF_CMDL_CMD8,
  1292. WOLFSSL_CONF_TYPE_STRING, NULL},
  1293. /* cmd CipherString */
  1294. {WOLFSSL_CONF_FILE_CMD9, WOLFSSL_CONF_CMDL_CMD9,
  1295. WOLFSSL_CONF_TYPE_STRING, cmdfunc_cipherstring},
  1296. #if !defined(NO_DH) && !defined(NO_BIO)
  1297. /* cmd DHParameters */
  1298. {WOLFSSL_CONF_FILE_CMD10, WOLFSSL_CONF_CMDL_CMD10,
  1299. WOLFSSL_CONF_TYPE_FILE, cmdfunc_dhparam},
  1300. #endif
  1301. #ifdef HAVE_ECC
  1302. /* cmd ECHDParameters */
  1303. {WOLFSSL_CONF_FILE_CMD11, WOLFSSL_CONF_CMDL_CMD11,
  1304. WOLFSSL_CONF_TYPE_STRING, NULL},
  1305. #endif
  1306. };
  1307. /* size of command table */
  1308. static const size_t size_of_cmd_tbls = sizeof(conf_cmds_tbl)
  1309. / sizeof(conf_cmd_tbl);
  1310. static const conf_cmd_tbl* wolfssl_conf_find_cmd(WOLFSSL_CONF_CTX* cctx,
  1311. const char* cmd)
  1312. {
  1313. size_t i = 0;
  1314. size_t cmdlen = 0;
  1315. if (cctx->flags & WOLFSSL_CONF_FLAG_CMDLINE) {
  1316. cmdlen = XSTRLEN(cmd);
  1317. if (cmdlen < 2) {
  1318. WOLFSSL_MSG("bad cmdline command");
  1319. return NULL;
  1320. }
  1321. /* skip "-" prefix */
  1322. ++cmd;
  1323. }
  1324. for (i = 0; i < size_of_cmd_tbls; i++) {
  1325. /* check if the cmd is valid */
  1326. if (cctx->flags & WOLFSSL_CONF_FLAG_CMDLINE) {
  1327. if (conf_cmds_tbl[i].cmdline_cmd != NULL &&
  1328. XSTRCMP(cmd, conf_cmds_tbl[i].cmdline_cmd) == 0) {
  1329. return &conf_cmds_tbl[i];
  1330. }
  1331. }
  1332. if (cctx->flags & WOLFSSL_CONF_FLAG_FILE) {
  1333. if (conf_cmds_tbl[i].file_cmd != NULL &&
  1334. XSTRCMP(cmd, conf_cmds_tbl[i].file_cmd) == 0) {
  1335. return &conf_cmds_tbl[i];
  1336. }
  1337. }
  1338. }
  1339. return NULL;
  1340. }
  1341. /**
  1342. * send configuration command
  1343. * @param cctx a pointer to WOLFSSL_CONF_CTX structure
  1344. * @param cmd configuration command
  1345. * @param value arguments for cmd
  1346. * @return 1 when cmd is recognised, but value is not used
  1347. * 2 both cmd and value are used
  1348. * otherwise WOLFSSL_FAILURE
  1349. * -2 if cmd is not recognised
  1350. * -3 if value is NULL, but cmd is recognized
  1351. */
  1352. int wolfSSL_CONF_cmd(WOLFSSL_CONF_CTX* cctx, const char* cmd, const char* value)
  1353. {
  1354. int ret = WOLFSSL_FAILURE;
  1355. const conf_cmd_tbl* confcmd = NULL;
  1356. WOLFSSL_ENTER("wolfSSL_CONF_cmd");
  1357. /* sanity check */
  1358. if (cctx == NULL || cmd == NULL) {
  1359. WOLFSSL_MSG("bad arguments");
  1360. return ret;
  1361. }
  1362. confcmd = wolfssl_conf_find_cmd(cctx, cmd);
  1363. if (confcmd == NULL)
  1364. return -2;
  1365. if (confcmd->cmdfunc == NULL) {
  1366. WOLFSSL_MSG("cmd not yet implemented");
  1367. return -2;
  1368. }
  1369. ret = confcmd->cmdfunc(cctx, value);
  1370. /* return code compliant with OpenSSL */
  1371. if (ret < -3)
  1372. ret = 0;
  1373. WOLFSSL_LEAVE("wolfSSL_CONF_cmd", ret);
  1374. return ret;
  1375. }
  1376. /**
  1377. *
  1378. * @param cctx a pointer to WOLFSSL_CONF_CTX structure
  1379. * @param cmd configuration command
  1380. * @return The SSL_CONF_TYPE_* type or SSL_CONF_TYPE_UNKNOWN if an
  1381. * unvalid command
  1382. */
  1383. int wolfSSL_CONF_cmd_value_type(WOLFSSL_CONF_CTX *cctx, const char *cmd)
  1384. {
  1385. const conf_cmd_tbl* confcmd = NULL;
  1386. WOLFSSL_ENTER("wolfSSL_CONF_cmd_value_type");
  1387. confcmd = wolfssl_conf_find_cmd(cctx, cmd);
  1388. if (confcmd == NULL)
  1389. return SSL_CONF_TYPE_UNKNOWN;
  1390. return (int)confcmd->data_type;
  1391. }
  1392. #endif /* OPENSSL_EXTRA */
  1393. /*******************************************************************************
  1394. * END OF CONF API
  1395. ******************************************************************************/
  1396. #endif /* WOLFSSL_CONF_INCLUDED */