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. wolfSSL_TXT_DB_free(ret);
  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 i;
  148. WOLFSSL_ENTER("wolfSSL_TXT_DB_write");
  149. if (!out || !db || !db->num_fields) {
  150. WOLFSSL_MSG("Bad parameter");
  151. return WOLFSSL_FAILURE;
  152. }
  153. data = db->data;
  154. while (data) {
  155. char** fields = (char**)data->data.string;
  156. char* idx = buf;
  157. int sz;
  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. wolfssl_sk_pop_type(sk, STACK_TYPE_CONF_VALUE);
  402. return WOLFSSL_FAILURE;
  403. }
  404. return WOLFSSL_SUCCESS;
  405. }
  406. WOLFSSL_CONF_VALUE *wolfSSL_CONF_new_section(WOLFSSL_CONF *conf,
  407. const char *section)
  408. {
  409. WOLFSSL_CONF_VALUE* ret = NULL;
  410. WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
  411. int slen;
  412. WOLFSSL_ENTER("wolfSSL_CONF_new_section");
  413. if (!conf || !section) {
  414. WOLFSSL_MSG("Bad parameter");
  415. return NULL;
  416. }
  417. slen = (int)XSTRLEN(section);
  418. if (!(ret = wolfSSL_CONF_VALUE_new())) {
  419. WOLFSSL_MSG("wolfSSL_CONF_new error");
  420. goto error;
  421. }
  422. if (!(ret->section = (char*)XMALLOC(slen+1, NULL, DYNAMIC_TYPE_OPENSSL))) {
  423. WOLFSSL_MSG("section malloc error");
  424. goto error;
  425. }
  426. XMEMCPY(ret->section, section, slen+1);
  427. if (!(sk = wolfSSL_sk_CONF_VALUE_new(NULL))) {
  428. WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_new error");
  429. goto error;
  430. }
  431. ret->value = (char*)sk;
  432. if (wolfSSL_sk_CONF_VALUE_push(conf->data, ret) != WOLFSSL_SUCCESS) {
  433. WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error");
  434. goto error;
  435. }
  436. return ret;
  437. error:
  438. if (ret) {
  439. /* NULL so that wolfSSL_X509V3_conf_free doesn't attempt to free it */
  440. ret->value = NULL;
  441. wolfSSL_X509V3_conf_free(ret);
  442. }
  443. if (sk) {
  444. wolfSSL_sk_CONF_VALUE_free(sk);
  445. }
  446. return NULL;
  447. }
  448. WOLFSSL_CONF_VALUE *wolfSSL_CONF_get_section(WOLFSSL_CONF *conf,
  449. const char *section)
  450. {
  451. WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
  452. WOLFSSL_ENTER("wolfSSL_CONF_get_section");
  453. if (!conf || !section) {
  454. WOLFSSL_MSG("Bad parameter");
  455. return NULL;
  456. }
  457. sk = conf->data;
  458. while (sk) {
  459. WOLFSSL_CONF_VALUE* val = sk->data.conf;
  460. if (val) {
  461. if (!val->name && XSTRCMP(section, val->section) == 0) {
  462. return val;
  463. }
  464. }
  465. sk = sk->next;
  466. }
  467. return NULL;
  468. }
  469. WOLFSSL_CONF *wolfSSL_NCONF_new(void *meth)
  470. {
  471. WOLFSSL_CONF* ret;
  472. WOLFSSL_ENTER("wolfSSL_NCONF_new");
  473. if (meth) {
  474. WOLFSSL_MSG("wolfSSL does not support CONF_METHOD");
  475. }
  476. ret = (WOLFSSL_CONF*)XMALLOC(sizeof(WOLFSSL_CONF), NULL, DYNAMIC_TYPE_OPENSSL);
  477. if (ret) {
  478. XMEMSET(ret, 0, sizeof(WOLFSSL_CONF));
  479. ret->data = wolfSSL_sk_CONF_VALUE_new(NULL);
  480. if (!ret->data) {
  481. wolfSSL_NCONF_free(ret);
  482. return NULL;
  483. }
  484. }
  485. return ret;
  486. }
  487. char *wolfSSL_NCONF_get_string(const WOLFSSL_CONF *conf,
  488. const char *group, const char *name)
  489. {
  490. WOLFSSL_CONF_VALUE find_val;
  491. WOLFSSL_CONF_VALUE *val;
  492. WOLFSSL_ENTER("wolfSSL_NCONF_get_string");
  493. if (!conf) {
  494. #ifdef HAVE_SECURE_GETENV
  495. return secure_getenv(name);
  496. #else
  497. WOLFSSL_MSG("Missing secure_getenv");
  498. return NULL;
  499. #endif
  500. }
  501. find_val.name = (char *)name;
  502. if (group) {
  503. find_val.section = (char *)group;
  504. val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val);
  505. if (val)
  506. return val->value;
  507. if (XSTRCMP(group, "ENV") == 0) {
  508. #ifdef HAVE_SECURE_GETENV
  509. return secure_getenv(name);
  510. #else
  511. WOLFSSL_MSG("Missing secure_getenv");
  512. return NULL;
  513. #endif
  514. }
  515. }
  516. find_val.section = (char *)"default";
  517. val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val);
  518. if (val)
  519. return val->value;
  520. else
  521. return NULL;
  522. }
  523. int wolfSSL_NCONF_get_number(const CONF *conf, const char *group,
  524. const char *name, long *result)
  525. {
  526. char *str;
  527. WOLFSSL_ENTER("wolfSSL_NCONF_get_number");
  528. if (!conf || !name || !result) {
  529. WOLFSSL_MSG("Bad parameter");
  530. return WOLFSSL_FAILURE;
  531. }
  532. if (!(str = wolfSSL_NCONF_get_string(conf, group, name))) {
  533. WOLFSSL_MSG("wolfSSL_NCONF_get_string error");
  534. return WOLFSSL_FAILURE;
  535. }
  536. *result = atol(str);
  537. return WOLFSSL_SUCCESS;
  538. }
  539. /**
  540. * The WOLFSSL_CONF->value member is treated as a
  541. * WOLFSSL_STACK_OF(WOLFSSL_CONF_VALUE) which becomes
  542. * the return value.
  543. * @param conf
  544. * @param section
  545. * @return WOLFSSL_STACK_OF(WOLFSSL_CONF_VALUE)
  546. */
  547. WOLFSSL_STACK *wolfSSL_NCONF_get_section(
  548. const WOLFSSL_CONF *conf, const char *section)
  549. {
  550. WOLFSSL_CONF_VALUE *val;
  551. WOLFSSL_CONF_VALUE find_val;
  552. WOLFSSL_ENTER("wolfSSL_NCONF_get_section");
  553. if (!conf || !section) {
  554. WOLFSSL_MSG("Bad parameter");
  555. return NULL;
  556. }
  557. find_val.name = NULL;
  558. find_val.section = (char*)section;
  559. val = wolfSSL_lh_WOLFSSL_CONF_VALUE_retrieve(conf->data, &find_val);
  560. if (val)
  561. return (WOLFSSL_STACK*)val->value;
  562. else
  563. return NULL;
  564. }
  565. #if !defined(NO_BIO)
  566. static WOLFSSL_CONF_VALUE *wolfSSL_CONF_VALUE_new_values(char* section,
  567. char* name, char* value)
  568. {
  569. WOLFSSL_CONF_VALUE* ret;
  570. int len;
  571. WOLFSSL_ENTER("wolfSSL_CONF_VALUE_new_values");
  572. if (!(ret = wolfSSL_CONF_VALUE_new())) {
  573. WOLFSSL_MSG("wolfSSL_CONF_VALUE_new error");
  574. return NULL;
  575. }
  576. if (section) {
  577. len = (int)XSTRLEN(section);
  578. ret->section = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL);
  579. if (!ret->section) {
  580. WOLFSSL_MSG("malloc error");
  581. wolfSSL_X509V3_conf_free(ret);
  582. return NULL;
  583. }
  584. XMEMCPY(ret->section, section, len+1);
  585. }
  586. if (name) {
  587. len = (int)XSTRLEN(name);
  588. ret->name = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL);
  589. if (!ret->name) {
  590. WOLFSSL_MSG("malloc error");
  591. wolfSSL_X509V3_conf_free(ret);
  592. return NULL;
  593. }
  594. XMEMCPY(ret->name, name, len+1);
  595. }
  596. if (value) {
  597. len = (int)XSTRLEN(value);
  598. ret->value = (char*)XMALLOC(len+1, NULL, DYNAMIC_TYPE_OPENSSL);
  599. if (!ret->value) {
  600. WOLFSSL_MSG("malloc error");
  601. wolfSSL_X509V3_conf_free(ret);
  602. return NULL;
  603. }
  604. XMEMCPY(ret->value, value, len+1);
  605. }
  606. return ret;
  607. }
  608. static char* expandValue(WOLFSSL_CONF *conf, const char* section,
  609. char *str)
  610. {
  611. int strLen = (int)XSTRLEN(str);
  612. char* ret = NULL;
  613. /* Check to see if there is anything to expand */
  614. if (XSTRNSTR(str, "$", strLen)) {
  615. int idx = 0;
  616. char* strIdx = str;
  617. ret = (char*)XMALLOC(strLen + 1, NULL, DYNAMIC_TYPE_OPENSSL);
  618. if (!ret) {
  619. WOLFSSL_MSG("malloc error");
  620. return str;
  621. }
  622. while (*strIdx) {
  623. if (*strIdx == '$') {
  624. /* Expand variable */
  625. char* startIdx = ++strIdx;
  626. char* endIdx;
  627. const char* s = section;
  628. const char* value;
  629. char prevValue;
  630. if (*startIdx == '{') {
  631. /* First read the section.
  632. * format: ${section_name::var_name} */
  633. s = ++startIdx;
  634. while (*strIdx && *strIdx != ':') strIdx++;
  635. if (!*strIdx || s == strIdx || strIdx[1] != ':') {
  636. WOLFSSL_MSG("invalid section name in "
  637. "variable expansion");
  638. goto expand_cleanup;
  639. }
  640. *strIdx = '\0';
  641. strIdx += 2;
  642. startIdx = strIdx;
  643. }
  644. while (*strIdx && (XISALNUM((int)(*strIdx)) || *strIdx == '_'))
  645. strIdx++;
  646. endIdx = strIdx;
  647. if (startIdx == endIdx) {
  648. WOLFSSL_MSG("invalid variable name in config");
  649. goto expand_cleanup;
  650. }
  651. if (s != section) {
  652. /* We are expecting a trailing '}' */
  653. if (*strIdx != '}') {
  654. WOLFSSL_MSG("Missing '}' in variable");
  655. goto expand_cleanup;
  656. }
  657. strIdx++;
  658. }
  659. /* Save char value at the end of the name so that we can place
  660. * a null char there. */
  661. prevValue = *endIdx;
  662. *endIdx = '\0';
  663. value = wolfSSL_NCONF_get_string(conf, s, startIdx);
  664. *endIdx = prevValue;
  665. /* Skip copy if no value or zero-length value */
  666. if (value && *value) {
  667. int valueLen = (int)XSTRLEN(value);
  668. char* newRet;
  669. /* This will allocate slightly more memory than necessary
  670. * but better be safe */
  671. strLen += valueLen;
  672. newRet = (char*)XREALLOC(ret, strLen + 1, NULL,
  673. DYNAMIC_TYPE_OPENSSL);
  674. if (!newRet) {
  675. WOLFSSL_MSG("realloc error");
  676. goto expand_cleanup;
  677. }
  678. ret = newRet;
  679. XMEMCPY(ret + idx, value, valueLen);
  680. idx += valueLen;
  681. }
  682. }
  683. else {
  684. ret[idx++] = *strIdx++;
  685. }
  686. }
  687. ret[idx] = '\0';
  688. }
  689. return ret ? ret : str;
  690. expand_cleanup:
  691. if (ret)
  692. XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL);
  693. return NULL;
  694. }
  695. #define SKIP_WHITESPACE(idx, max_idx) \
  696. while ((idx) < (max_idx) && (*(idx) == ' ' || *(idx) == '\t')) \
  697. {(idx)++;}
  698. int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline)
  699. {
  700. int ret = WOLFSSL_FAILURE;
  701. WOLFSSL_BIO *in = NULL;
  702. char* buf = NULL;
  703. char* idx = NULL;
  704. char* bufEnd = NULL;
  705. CONF_VALUE* section = NULL;
  706. long line = 0;
  707. int bufLen = 0;
  708. if (!conf || !file) {
  709. WOLFSSL_MSG("Bad parameter");
  710. return WOLFSSL_FAILURE;
  711. }
  712. /* Open file */
  713. if (!(in = wolfSSL_BIO_new_file(file, "rb"))) {
  714. WOLFSSL_MSG("wolfSSL_BIO_new_file error");
  715. return WOLFSSL_FAILURE;
  716. }
  717. /* Read file */
  718. bufLen = wolfSSL_BIO_get_len(in);
  719. if (bufLen <= 0) {
  720. WOLFSSL_MSG("wolfSSL_BIO_get_len error");
  721. goto cleanup;
  722. }
  723. if (!(buf = (char*)XMALLOC(bufLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER))) {
  724. WOLFSSL_MSG("malloc error");
  725. goto cleanup;
  726. }
  727. if (wolfSSL_BIO_read(in, buf, bufLen) != bufLen) {
  728. WOLFSSL_MSG("wolfSSL_BIO_read error");
  729. goto cleanup;
  730. }
  731. if (!(section = wolfSSL_CONF_new_section(conf, "default"))) {
  732. WOLFSSL_MSG("wolfSSL_CONF_new_section error");
  733. goto cleanup;
  734. }
  735. /* LETS START READING SOME CONFIGS */
  736. idx = buf;
  737. bufEnd = buf + bufLen;
  738. while (idx < bufEnd) {
  739. char* lineEnd = XSTRNSTR(idx, "\n", (unsigned int)(bufEnd - idx));
  740. char* maxIdx;
  741. if (!lineEnd)
  742. lineEnd = bufEnd; /* Last line in file */
  743. maxIdx = XSTRNSTR(idx, "#", (unsigned int)(lineEnd - idx));
  744. if (!maxIdx)
  745. maxIdx = lineEnd;
  746. line++;
  747. SKIP_WHITESPACE(idx, maxIdx);
  748. if (idx == maxIdx) {
  749. /* Empty line */
  750. idx = lineEnd + 1;
  751. continue;
  752. }
  753. if (*idx == '[') {
  754. /* New section. Spaces not allowed in section name. */
  755. char* sectionName;
  756. int sectionNameLen;
  757. if (idx < maxIdx)
  758. idx++;
  759. else {
  760. WOLFSSL_MSG("Invalid section definition.");
  761. goto cleanup;
  762. }
  763. SKIP_WHITESPACE(idx, maxIdx);
  764. sectionName = idx;
  765. /* Find end of section name */
  766. while (idx < maxIdx && *idx != ' ' && *idx != ']')
  767. idx++;
  768. sectionNameLen = (int)(idx - sectionName);
  769. SKIP_WHITESPACE(idx, maxIdx);
  770. if (*idx != ']') {
  771. WOLFSSL_MSG("Section definition error. "
  772. "Closing brace not found.");
  773. goto cleanup;
  774. }
  775. sectionName[sectionNameLen] = '\0';
  776. if (!(section = wolfSSL_CONF_get_section(conf, sectionName))) {
  777. section = wolfSSL_CONF_new_section(conf, sectionName);
  778. if (!section)
  779. goto cleanup;
  780. }
  781. }
  782. else {
  783. char* name;
  784. int nameLen;
  785. char* value;
  786. char* exValue; /* expanded value */
  787. int valueLen;
  788. WOLFSSL_CONF_VALUE* newVal = NULL;
  789. SKIP_WHITESPACE(idx, maxIdx);
  790. name = idx;
  791. /* Find end of name */
  792. while (idx < maxIdx && *idx != ' ' && *idx != '=')
  793. idx++;
  794. nameLen = (int)(idx - name);
  795. SKIP_WHITESPACE(idx, maxIdx);
  796. if (*idx != '=') {
  797. WOLFSSL_MSG("Missing equals sign");
  798. goto cleanup;
  799. }
  800. idx++;
  801. SKIP_WHITESPACE(idx, maxIdx);
  802. value = idx;
  803. /* Find end of value */
  804. idx = maxIdx-1;
  805. while (idx >= value && (*idx == ' ' || *idx == '\t' || *idx == '\r'))
  806. idx--;
  807. valueLen = (int)(idx - value + 1);
  808. /* Sanity checks */
  809. if (nameLen <= 0 || valueLen <= 0) {
  810. WOLFSSL_MSG("Sanity checks failed");
  811. goto cleanup;
  812. }
  813. name[nameLen] = '\0';
  814. value[valueLen] = '\0';
  815. if (!(exValue = expandValue(conf, section->section, value))) {
  816. WOLFSSL_MSG("Variable expansion failed");
  817. goto cleanup;
  818. }
  819. if (!(newVal = wolfSSL_CONF_VALUE_new_values(NULL,
  820. name, exValue))) {
  821. WOLFSSL_MSG("wolfSSL_CONF_VALUE_new_values error");
  822. if (exValue != value)
  823. XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL);
  824. goto cleanup;
  825. }
  826. if (exValue != value)
  827. XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL);
  828. if (wolfSSL_CONF_add_string(conf, section, newVal) !=
  829. WOLFSSL_SUCCESS) {
  830. wolfSSL_X509V3_conf_free(newVal);
  831. WOLFSSL_MSG("wolfSSL_CONF_add_string error");
  832. goto cleanup;
  833. }
  834. }
  835. idx = lineEnd + 1;
  836. }
  837. ret = WOLFSSL_SUCCESS;
  838. cleanup:
  839. if (in)
  840. wolfSSL_BIO_free(in);
  841. if (buf)
  842. XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  843. if (eline)
  844. *eline = line;
  845. return ret;
  846. }
  847. #endif /* !NO_BIO */
  848. void wolfSSL_NCONF_free(WOLFSSL_CONF *conf)
  849. {
  850. WOLFSSL_ENTER("wolfSSL_NCONF_free");
  851. if (conf) {
  852. wolfSSL_sk_CONF_VALUE_free(conf->data);
  853. XFREE(conf, NULL, DYNAMIC_TYPE_OPENSSL);
  854. }
  855. }
  856. void wolfSSL_X509V3_conf_free(WOLFSSL_CONF_VALUE *val)
  857. {
  858. WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL;
  859. if (val) {
  860. if (val->name) {
  861. /* Not a section. Don't free section as it is a shared pointer. */
  862. XFREE(val->name, NULL, DYNAMIC_TYPE_OPENSSL);
  863. if (val->value)
  864. XFREE(val->value, NULL, DYNAMIC_TYPE_OPENSSL);
  865. }
  866. else {
  867. /* Section so val->value is a stack */
  868. if (val->section)
  869. XFREE(val->section, NULL, DYNAMIC_TYPE_OPENSSL);
  870. /* Only free the stack structures. The contained conf values
  871. * will be freed in wolfSSL_NCONF_free */
  872. sk = (WOLF_STACK_OF(WOLFSSL_CONF_VALUE)*)val->value;
  873. while (sk) {
  874. WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *tmp = sk->next;
  875. XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
  876. sk = tmp;
  877. }
  878. }
  879. XFREE(val, NULL, DYNAMIC_TYPE_OPENSSL);
  880. }
  881. }
  882. WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new(
  883. WOLF_SK_COMPARE_CB(WOLFSSL_CONF_VALUE, compFunc))
  884. {
  885. WOLFSSL_STACK* ret;
  886. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_new");
  887. ret = wolfSSL_sk_new_node(NULL);
  888. if (!ret)
  889. return NULL;
  890. ret->hash_fn = (wolf_sk_hash_cb)wolfSSL_CONF_VALUE_hash;
  891. ret->type = STACK_TYPE_CONF_VALUE;
  892. (void)compFunc;
  893. return ret;
  894. }
  895. /* Free the structure for WOLFSSL_CONF_VALUE stack
  896. *
  897. * sk stack to free nodes in
  898. */
  899. void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk)
  900. {
  901. WOLFSSL_STACK* tmp;
  902. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_free");
  903. if (sk == NULL)
  904. return;
  905. /* parse through stack freeing each node */
  906. while (sk) {
  907. tmp = sk->next;
  908. wolfSSL_X509V3_conf_free(sk->data.conf);
  909. XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
  910. sk = tmp;
  911. }
  912. }
  913. int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk)
  914. {
  915. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_num");
  916. if (sk)
  917. return wolfSSL_sk_num(sk);
  918. return 0;
  919. }
  920. WOLFSSL_CONF_VALUE *wolfSSL_sk_CONF_VALUE_value(const WOLFSSL_STACK *sk, int i)
  921. {
  922. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_value");
  923. if (sk)
  924. return (WOLFSSL_CONF_VALUE*)wolfSSL_sk_value(sk, i);
  925. return NULL;
  926. }
  927. /* return 1 on success 0 on fail */
  928. int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk,
  929. WOLFSSL_CONF_VALUE* val)
  930. {
  931. WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_push");
  932. if (sk == NULL || val == NULL) {
  933. return WOLFSSL_FAILURE;
  934. }
  935. return wolfSSL_sk_push(sk, val);
  936. }
  937. #endif /* !NO_CERTS && OPENSSL_EXTRA && OPENSSL_ALL */
  938. #ifdef OPENSSL_EXTRA
  939. #ifndef NO_WOLFSSL_STUB
  940. /* Returns default file name and path of config file. However
  941. a wolfssl.cnf file is not currently supported */
  942. char* wolfSSL_CONF_get1_default_config_file(void)
  943. {
  944. WOLFSSL_ENTER("wolfSSL_CONF_get1_default_config_file");
  945. WOLFSSL_STUB("CONF_get1_default_config_file");
  946. return NULL;
  947. }
  948. #endif
  949. /**
  950. * Allocate WOLFSSL_CONF_CTX instance
  951. * @return pointer to WOLFSSL_CONF_CTX structure on success and NULL on fail
  952. */
  953. WOLFSSL_CONF_CTX* wolfSSL_CONF_CTX_new(void)
  954. {
  955. WOLFSSL_CONF_CTX* cctx;
  956. WOLFSSL_ENTER("wolfSSL_CONF_CTX_new");
  957. cctx = (WOLFSSL_CONF_CTX*)XMALLOC(sizeof(WOLFSSL_CONF_CTX), NULL,
  958. DYNAMIC_TYPE_OPENSSL);
  959. if (!cctx) {
  960. WOLFSSL_MSG("malloc error");
  961. return NULL;
  962. }
  963. XMEMSET(cctx, 0, sizeof(WOLFSSL_CONF_CTX));
  964. return cctx;
  965. }
  966. /**
  967. * Release WOLFSSL_CONF_CTX instance
  968. * @param cctx a pointer to WOLFSSL_CONF_CTX structure to be freed
  969. */
  970. void wolfSSL_CONF_CTX_free(WOLFSSL_CONF_CTX* cctx)
  971. {
  972. WOLFSSL_ENTER("wolfSSL_CONF_CTX_free");
  973. XFREE(cctx, NULL, DYNAMIC_TYPE_OPENSSL);
  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 flag 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. if (cctx->flags & WOLFSSL_CONF_FLAG_CMDLINE) {
  1315. size_t cmdlen = XSTRLEN(cmd);
  1316. if (cmdlen < 2) {
  1317. WOLFSSL_MSG("bad cmdline command");
  1318. return NULL;
  1319. }
  1320. /* skip "-" prefix */
  1321. ++cmd;
  1322. }
  1323. for (i = 0; i < size_of_cmd_tbls; i++) {
  1324. /* check if the cmd is valid */
  1325. if (cctx->flags & WOLFSSL_CONF_FLAG_CMDLINE) {
  1326. if (conf_cmds_tbl[i].cmdline_cmd != NULL &&
  1327. XSTRCMP(cmd, conf_cmds_tbl[i].cmdline_cmd) == 0) {
  1328. return &conf_cmds_tbl[i];
  1329. }
  1330. }
  1331. if (cctx->flags & WOLFSSL_CONF_FLAG_FILE) {
  1332. if (conf_cmds_tbl[i].file_cmd != NULL &&
  1333. XSTRCMP(cmd, conf_cmds_tbl[i].file_cmd) == 0) {
  1334. return &conf_cmds_tbl[i];
  1335. }
  1336. }
  1337. }
  1338. return NULL;
  1339. }
  1340. /**
  1341. * send configuration command
  1342. * @param cctx a pointer to WOLFSSL_CONF_CTX structure
  1343. * @param cmd configuration command
  1344. * @param value arguments for cmd
  1345. * @return 1 when cmd is recognised, but value is not used
  1346. * 2 both cmd and value are used
  1347. * otherwise WOLFSSL_FAILURE
  1348. * -2 if cmd is not recognised
  1349. * -3 if value is NULL, but cmd is recognized
  1350. */
  1351. int wolfSSL_CONF_cmd(WOLFSSL_CONF_CTX* cctx, const char* cmd, const char* value)
  1352. {
  1353. int ret = WOLFSSL_FAILURE;
  1354. const conf_cmd_tbl* confcmd = NULL;
  1355. WOLFSSL_ENTER("wolfSSL_CONF_cmd");
  1356. /* sanity check */
  1357. if (cctx == NULL || cmd == NULL) {
  1358. WOLFSSL_MSG("bad arguments");
  1359. return ret;
  1360. }
  1361. confcmd = wolfssl_conf_find_cmd(cctx, cmd);
  1362. if (confcmd == NULL)
  1363. return -2;
  1364. if (confcmd->cmdfunc == NULL) {
  1365. WOLFSSL_MSG("cmd not yet implemented");
  1366. return -2;
  1367. }
  1368. ret = confcmd->cmdfunc(cctx, value);
  1369. /* return code compliant with OpenSSL */
  1370. if (ret < -3)
  1371. ret = 0;
  1372. WOLFSSL_LEAVE("wolfSSL_CONF_cmd", ret);
  1373. return ret;
  1374. }
  1375. /**
  1376. *
  1377. * @param cctx a pointer to WOLFSSL_CONF_CTX structure
  1378. * @param cmd configuration command
  1379. * @return The SSL_CONF_TYPE_* type or SSL_CONF_TYPE_UNKNOWN if an
  1380. * invalid command
  1381. */
  1382. int wolfSSL_CONF_cmd_value_type(WOLFSSL_CONF_CTX *cctx, const char *cmd)
  1383. {
  1384. const conf_cmd_tbl* confcmd = NULL;
  1385. WOLFSSL_ENTER("wolfSSL_CONF_cmd_value_type");
  1386. confcmd = wolfssl_conf_find_cmd(cctx, cmd);
  1387. if (confcmd == NULL)
  1388. return SSL_CONF_TYPE_UNKNOWN;
  1389. return (int)confcmd->data_type;
  1390. }
  1391. #endif /* OPENSSL_EXTRA */
  1392. /*******************************************************************************
  1393. * END OF CONF API
  1394. ******************************************************************************/
  1395. #endif /* WOLFSSL_CONF_INCLUDED */