conf.c 45 KB

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